/*****************************************************************************
本程序对循环链表进行处理,分别对链表的长度进行设定、插入、删除和释放,
并且通过对操作者的限制来防止因操作者的操作失误而带来的不可设想的后果,本程序
有较强的安全性程序的细节如下:
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct stu //定义TYM结构体类型
{
char name[20];
int score;
struct stu *llink,*rlink; //llink为左链域指针,rlink为右链域指针
}TYM;
TYM *Insert(TYM*head) //插入结点函数
{
int i;
int pos,len;
TYM *a,*s,*p,*q;
printf("*********** Insert *************\n");
if(head->llink!=NULL) //如果链表存在
{
for(p=head->rlink,i=2;p!=head;p=p->rlink,i++); //检测链表的长度
printf("Position(No More Than %d): ",i); //提示输入的值的范围
scanf("%d",&pos); //输入插入的位置
while(pos<0||pos>i) //如果输入负数
{
printf("Please enter the correct!\nPosition(No More Than %d): ",i);
scanf("%d",&pos); //输入插入的位置
}
}
printf("Lenth:\t\t\t");
scanf("%d",&len); //输入插入的结点个数
while(len<0) //如果输入负数
{
printf("Please enter the correct!\nLenth:\t\t\t");
scanf("%d",&len); //输入插入的结点个数
}
if(len==0)return head; //如果插入的结点数是0则返回head
printf("Name:\tScore:\n");
a = (TYM*)calloc(1,sizeof(TYM)); //开辟一个空间,并将空间的首地址给a
scanf("%s%d",a->name,&a->score); //对a进行赋值
for(p=a,i=1;i<len;i++) //创造len个结点并赋值
{
q = (TYM*)malloc(sizeof(TYM)); //开辟一个新的空间
scanf("%s%d",q->name,&q->score); //对新空间赋值
p->rlink = q; //使p的右链域指针指向q
q->llink = p; //使q的左链域指针指向p
p = q; //使p指向q
}
a->llink = p; //使新链表的左链域指针指向最后一个地址
p->rlink = a; //使链表的最后一个变量的右链域指针指向新链表的首地址
if(head->llink==NULL)return a; //如果链表存在,则返回a作首地址
for(s=head,i=1;i<pos;i++) //查找插入的位置
{
s = s->rlink; //使s指向右边的下一个结点
}
q = s->llink; //将s的左链域指针的值保存到q中
p->rlink = s; //使链表的最后一个变量的右链域指针指向S
s->llink = p; //使s的左链域指针指向新链表的最后一个地址
a->llink = q; //使新链表的首地址的左链域指针指向q
q->rlink = a; //使原链表的断开结点的右链域指针指向新链表的首地址
return pos==1?a:head;//如果插入的位置为第一个,则返回a作首地址
}
TYM *DeleteNode(TYM *head) //删除结点函数
{
int pos,len,i;
TYM *s,*Llink,*Rlink;
if(head->llink==NULL)return head; //如里链表不存在则返回head
for(s=head->rlink,i=1;s!=head;s=s->rlink,i++); //检测链表的长度
printf("*********** Delete *************\nPosition(No More Than %d):\t",i);
scanf("%d",&pos); //输入要删除的结点的位置
while(pos<0||pos>i) //如果输入负数
{
printf("Please enter the correct!\nPosition(No More Than %d):\t",i);
scanf("%d",&pos); //输入要删除的结点的位置
}
printf("Lenth(No More Than %d):\t\t",i);
scanf("%d",&len); //输入删除个数
while(len<0||len>i-pos+1) //如果输入负数
{
printf("Please enter the correct!\nLenth(No More Than %d):\t\t",i);
scanf("%d",&len); //输入删除个数
}
if(len==0||i==1) return head; //如果不删除或只有一个结点则返回head
for(s=head,i=1;i<pos;i++) //查找删除的始点位置
{
s = s->rlink;
}
for(i=0;i<len;i++) //删除len个结点
{
Llink = s->llink; //将删除点的左链域指针保存到Llink
Rlink = s->rlink;//将删除点的右链域指针保存到Rlink
Rlink->llink = Llink;//将删除点的右边连接到左边
Llink->rlink = Rlink;//将删除点的左边连接到右边
free(s); //释放删除点
s = Rlink; //使s指向右边的下一个
}
return pos==1?s:head;//如果插入的是首地址则返回S作首地址
}
void Release(TYM *head) //释放函数
{
TYM *p,*q;
p = head->rlink; //使p指向首地址的右边第一个地址
for(q=head;p!=q;head=p) //释放链表
{
p = head->rlink; //p指向右边的下一个地址
free(head); //释放当前地址
}
if(head==q) //如果释放完所有结点
printf("******** Free success! *********\n");
}
void Print(TYM *head) //输出函数
{
TYM *p;
printf("*********** Output: ************\nName\tscore\n");
for(printf("%s\t%d\n",head->name,head->score),p=head->rlink;p!=head;p=p->rlink)
{ //输出整条链表
printf("%s\t%d\n",p->name,p->score); //输出当前结点的数据
}
}
int main()
{
TYM *head,*p,*q;
int len,i;
printf("************ Input: ************\n");
printf("Lenth:\t");
scanf("%d",&len); //输入长度
while(len<0) // 如果输入负数
{
printf("Please enter the correct!\n");
printf("Lenth:\t");
scanf("%d",&len);
}
head = (TYM*)calloc(1,sizeof(TYM));//开辟一个空间,并使head指向它
if(len==0)
{
head->llink = head->rlink = NULL; //如果长度为0,则使head的左、右链域指针都为null
}
else
{
printf("Name:\tScore:\n");
scanf("%s%d",head->name,&head->score); //对head赋值
if(len==1)
head->llink = head->rlink = head; //如果长度为1,则使head的左右链域指针都指向本身
else
{
for(p=head,i=1;i<len;i++) //如果长度大于1
{
q = (TYM*)malloc(sizeof(TYM)); //开辟新空间
scanf("%s%d",q->name,&q->score); //对新空间赋值
p->rlink = q; //使p的右链域指针指向新空间
q->llink = p; //使新空间的左链域指针指向p
p = q; //使p指向q
}
p->rlink = head; //使最后一个地址的右链域指针指向首地址
head->llink = p; //使首地址的左链域指针指向尾地址
}
}
if(head->llink!=NULL) Print(head); //如果链表存在则输出
head = (TYM*)Insert(head); //插入结点
if(head->llink!=NULL) Print(head); //如果链表存在则输出
head = (TYM*)DeleteNode(head); //删除结点并返回首地址
if(head->llink!=NULL) //如链表存在
{
Print(head); //输出链表
Release(head); //释放链表
}
else free(head); //释放head
return 0;
}
/*************************************** 调试窗口 *********************************************/