/*=============================================================
目的:動態鏈表的綜合操作
算法分析:1、構造第一個結構體作爲頭
2、以P2和P1爲遊碼在結構體移動
3、 p1負責存儲新創立的結構體,p2負責指向新創立的結構體
4、creat函數返回鏈表的頭
==============================================================
作者:最後的村長
時間:2009年12月21日
工具:DEV C++ 4.9.9.2
version:1.0
==============================================================*/ #include <stdio.h> #include <stdlib.h> //#define NULL 0
#define LEN sizeof(struct student) struct student {
long num;
int score;
struct student *next;
};//學生結構體定義,包含兩個數據:學號和成績
int n;//n爲全局變量,實現鏈表中元素個數的統計
struct student *create(void)//開闢動態鏈表函數
{
struct student *head;
struct student *p1,*p2;
n=0;
long int stu_id=1100;
p1=p2=(struct student *)malloc(LEN);//
p1->num=stu_id;
printf("請輸入1個學生的成績:\n");
scanf("%d",&(p1->score));//第一個學生結構體創立結束
head=NULL;
while(p1->score!=0)
{
n=n+1;//統計鏈表中結構體元素的個數
if(n==1)head=p1;//頭指針賦值
else p2->next=p1;//前一個結構體的next指向下一個結構體
//!注意上面語句的執行順序
p2=p1;//p2移向下一個結構體
p1=(struct student *)malloc(LEN);//新開闢一個結構體內存單元
stu_id=stu_id+2;
p1->num=stu_id;//對新開闢的結構體內元素初始化
printf("請輸入%d個學生的成績:\n",n+1);
printf("成績:");
scanf("%d",&(p1->score));
}
p2->next=NULL;
return head;
} /*=============================================================*/ void print(struct student *head) {
struct student *p;
printf("\n一共是 %d個學生成績如下 :\n",n);
p=head;
if(head!=NULL)
do
{
printf("%ld,%d\n",p->num,p->score);
p=p->next;
}while(p!=NULL);
}
/*=============================================================*/
struct student*del(struct student *head,long int delnum)
{
struct student *p1,*p2;
p2=p1=head;
if(head->num==delnum)//如果要刪除的學生是第一個的話
{
printf("刪除的學生是第一個\n");
head=head->next;
n--;//學生總數減一
}
else//刪除的學生不是第一個
{
while(p1->num!=delnum)//遍歷鏈表尋找要刪除的學生
{
p2=p1;
p1=p1->next;
}
if((p1->next==NULL)&&(p1->num!=delnum))//鏈表中無此要刪除的學生
printf("此鏈表中無要刪除的學生\n");
else if((p1->next==NULL)&&(p1->num==delnum))//要刪除的學生是最後一個
{
p2->next=NULL;
n--;//學生總數減一
}
else if(p1->num==delnum)//要刪除的學生是鏈表中的其中一個
{
p1=p1->next;
p2->next=p1;
n--;//學生總數減一
}
}
return head;
}
/*=============================================================*/
struct student *insert(struct student *head,struct student *p0)
{
struct student *p1,*p2;
p2=p1=head;//p1和p2指向頭指針
if((p0->num)<(head->num))//如果插入學生的學號小於第一個學生的學號
{
head=p0;
p0->next=p1;
}
else //如果插入學生的學號大於第一個學生的學號
{
while((p0->num)>(p1->num))//遍歷鏈表對學生的的學號進行對比
{
p2=p1;
p1=p1->next;
}
printf("p1當前指向的學生的序號是:%ld,成績是:%d,指向的下一個學生的地址是:%d\n\n",p1->num,p1->score,p1->next);
if(p1->next==NULL)//鏈表遍歷結束也沒有找到比插入學生的學號大的
{
p1->next=p0;
p0->next=NULL;
}
else if((p0->num)<=(p1->num))//
{
p2->next=p0;
p0->next=p1;
}
}
n++;
return (head);
}
int main() {
struct student *p,*head;
//======================創建並輸出鏈表
head=create();//創建鏈表
print(head);//打印創建後的鏈表
for(int i=0;i<10;i++)
{printf("========");}
puts("\n");
//===========================刪除一個學生
unsigned int delnum;//定義要刪除的學生號
printf("請輸入要刪除的學生號:\n");
scanf("%u",&delnum);//輸入要刪除學生號
head=del(head,delnum);//刪除學生號
printf("輸出刪除學號:%ld的學生後的鏈表\n",delnum);
print(head);//打印刪除後的學生號
for(int i=0;i<10;i++)
{printf("========");}
puts("\n");
//=====================插入一個學生
struct student stu;
//初始化待插入的學生的學號和成績
puts("請輸入待插入學生的學號:");
scanf("%ld",&stu.num);
puts("請輸入待插入學生的成績:");
scanf("%d",&stu.score);
head=insert(head,&stu);
printf("輸出插入學號:%ld,成績:%d的學生後的鏈表\n",stu.num,stu.score);
print(head);
for(int i=0;i<10;i++)
{printf("========");}
puts("\n");
//===================
system("PAUSE");
return 0; }
|