|
/*****************************************************************************
本程序?qū)ρh(huán)鏈表進(jìn)行處理,分別對(duì)鏈表的長度進(jìn)行設(shè)定、插入、刪除和釋放,
并且通過對(duì)操作者的限制來防止因操作者的操作失誤而帶來的不可設(shè)想的后果,本程序
有較強(qiáng)的安全性程序的細(xì)節(jié)如下:
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct stu //定義TYM結(jié)構(gòu)體類型
{
char name[20];
int score;
struct stu *llink,*rlink; // llink為左鏈域指針,rlink為右鏈域指針
}TYM;
TYM *Insert(TYM*head) //插入結(jié)點(diǎn)函數(shù)
{
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++); //檢測(cè)鏈表的長度
printf("Position(No More Than %d): ",i); //提示輸入的值的范圍
scanf("%d",&pos); //輸入插入的位置
while(pos<0||pos>i) //如果輸入負(fù)數(shù)
{
printf("Please enter the correct!\nPosition(No More Than %d): ",i);
scanf("%d",&pos); //輸入插入的位置
}
}
printf("Lenth:\t\t\t ");
scanf("%d",&len); //輸入插入的結(jié)點(diǎn)個(gè)數(shù)
while(len<0) //如果輸入負(fù)數(shù)
{
printf("Please enter the correct!\nLenth:\t\t\t ");
scanf("%d",&len); //輸入插入的結(jié)點(diǎn)個(gè)數(shù)
}
if(len==0) return head; //如果插入的結(jié)點(diǎn)數(shù)是0則返回head
printf("Name:\tScore:\n");
a = (TYM*)calloc(1,sizeof(TYM)); //開辟一個(gè)空間,并將空間的首地址給a
scanf("%s%d",a->name,&a->score); //對(duì)a進(jìn)行賦值
for(p=a,i=1;i<len;i++) //創(chuàng)造len個(gè)結(jié)點(diǎn)并賦值
{
q = (TYM*)malloc(sizeof(TYM)); //開辟一個(gè)新的空間
scanf("%s%d",q->name,&q->score); //對(duì)新空間賦值
p->rlink = q; //使p的右鏈域指針指向q
q->llink = p; //使q的左鏈域指針指向p
p = q; //使p指向q
}
a->llink = p; //使新鏈表的左鏈域指針指向最后一個(gè)地址
p->rlink = a; //使鏈表的最后一個(gè)變量的右鏈域指針指向新鏈表的首地址
if(head->llink==NULL) return a; //如果鏈表存在,則返回a作首地址
for(s=head,i=1;i<pos;i++) //查找插入的位置
{
s = s->rlink; //使s指向右邊的下一個(gè)結(jié)點(diǎn)
}
q = s->llink; //將s的左鏈域指針的值保存到q中
p->rlink = s; //使鏈表的最后一個(gè)變量的右鏈域指針指向S
s->llink = p; //使s的左鏈域指針指向新鏈表的最后一個(gè)地址
a->llink = q; //使新鏈表的首地址的左鏈域指針指向q
q->rlink = a; //使原鏈表的斷開結(jié)點(diǎn)的右鏈域指針指向新鏈表的首地址
return pos==1?a:head; //如果插入的位置為第一個(gè),則返回a作首地址
}
TYM *DeleteNode(TYM *head) //刪除結(jié)點(diǎn)函數(shù)
{
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++); //檢測(cè)鏈表的長度
printf("*********** Delete *************\nPosition(No More Than %d):\t",i);
scanf("%d",&pos); //輸入要?jiǎng)h除的結(jié)點(diǎn)的位置
while(pos<0||pos>i) //如果輸入負(fù)數(shù)
{
printf("Please enter the correct!\nPosition(No More Than %d):\t",i);
scanf("%d",&pos); //輸入要?jiǎng)h除的結(jié)點(diǎn)的位置
}
printf("Lenth(No More Than %d):\t\t",i);
scanf("%d",&len); //輸入刪除個(gè)數(shù)
while(len<0||len>i-pos+1) //如果輸入負(fù)數(shù)
{
printf("Please enter the correct!\nLenth(No More Than %d):\t\t",i);
scanf("%d",&len); //輸入刪除個(gè)數(shù)
}
if(len==0||i==1) return head; //如果不刪除或只有一個(gè)結(jié)點(diǎn)則返回head
for(s=head,i=1;i<pos;i++) //查找刪除的始點(diǎn)位置
{
s = s->rlink;
}
for(i=0;i<len;i++) //刪除len個(gè)結(jié)點(diǎn)
{
Llink = s->llink; //將刪除點(diǎn)的左鏈域指針保存到Llink
Rlink = s->rlink; //將刪除點(diǎn)的右鏈域指針保存到Rlink
Rlink->llink = Llink; //將刪除點(diǎn)的右邊連接到左邊
Llink->rlink = Rlink; //將刪除點(diǎn)的左邊連接到右邊
free(s); //釋放刪除點(diǎn)
s = Rlink; //使s指向右邊的下一個(gè)
}
return pos==1?s:head; //如果插入的是首地址則返回S作首地址
}
void Release(TYM *head) //釋放函數(shù)
{
TYM *p,*q;
p = head->rlink; //使p指向首地址的右邊第一個(gè)地址
for(q=head;p!=q;head=p) //釋放鏈表
{
p = head->rlink; //p指向右邊的下一個(gè)地址
free(head); //釋放當(dāng)前地址
}
if(head==q) //如果釋放完所有結(jié)點(diǎn)
printf("******** Free success! *********\n");
}
void Print(TYM *head) //輸出函數(shù)
{
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); //輸出當(dāng)前結(jié)點(diǎn)的數(shù)據(jù)
}
}
int main()
{
TYM *head,*p,*q;
int len,i;
printf("************ Input: ************\n");
printf("Lenth:\t");
scanf("%d",&len); //輸入長度
while(len<0) // 如果輸入負(fù)數(shù)
{
printf("Please enter the correct!\n");
printf("Lenth:\t");
scanf("%d",&len);
}
head = (TYM*)calloc(1,sizeof(TYM)); //開辟一個(gè)空間,并使head指向它
if(len==0)
{
head->llink = head->rlink = NULL; //如果長度為0,則使head的左、右鏈域指針都為null
}
else
{
printf("Name:\tScore:\n");
scanf("%s%d",head->name,&head->score); //對(duì)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); //對(duì)新空間賦值
p->rlink = q; //使p的右鏈域指針指向新空間
q->llink = p; //使新空間的左鏈域指針指向p
p = q; //使p指向q
}
p->rlink = head; //使最后一個(gè)地址的右鏈域指針指向首地址
head->llink = p; //使首地址的左鏈域指針指向尾地址
}
}
if(head->llink!=NULL) Print(head); //如果鏈表存在則輸出
head = (TYM*)Insert(head); //插入結(jié)點(diǎn)
if(head->llink!=NULL) Print(head); //如果鏈表存在則輸出
head = (TYM*)DeleteNode(head); //刪除結(jié)點(diǎn)并返回首地址
if(head->llink!=NULL) //如鏈表存在
{
Print(head); //輸出鏈表
Release(head); //釋放鏈表
}
else free(head); //釋放head
return 0;
}
/*************************************** 調(diào)試窗口 *********************************************/
|
|