/*****************************************************************************
本程序對循環鏈表進行處理,分別對鏈表的長度進行設定、插入、刪除和釋放,
并且通過對操作者的限制來防止因操作者的操作失誤而帶來的不可設想的后果,本程序
有較強的安全性程序的細節如下:
*****************************************************************************/
#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;
}
/*************************************** 調試窗口 *********************************************/
|