1. 程式人生 > >鏈表的創建,插入,刪除,輸出基本操作

鏈表的創建,插入,刪除,輸出基本操作

不能 head 提示信息 初始 list() 尾指針 tdi 初始化 %d

#include<stdio.h>
#include<cstdlib>
struct student //定義一個學生結點,結點包括值域和指針域
{
int num;//學號
char name[20];//姓名
char address[20];//地址
struct student *next;//定義結點的指針域,指向下一個結點
};
typedef struct student LIST;
LIST *CreateList();
LIST *InsertNode(LIST *h,LIST *s);
LIST *DeleteNode(LIST *h,long no);
void Display(LIST *h); int main()
{
LIST *head,*p;//定義指向結點的指針
long no;//定義學號變量
head=CreateList();//調用CreateList函數創建鏈表
printf("學號 姓名 地址\n");
Display(head);
printf("輸入要插入的結點\n");
p=(LIST *)malloc(sizeof(LIST));//動態的生成一個結點
scanf("%d %s %s",&p->num,&p->name,&p->address);
head=InsertNode(head,p);
printf("學號 姓名 地址\n");
Display(head);
printf("請輸入刪除結點的學號:\n");
scanf("%d",&no);
head=DeleteNode(head,no);
if(head!=NULL)
{
printf("學號 姓名 地址\n");
Display(head);
}
return 0;
} /*鏈表的創建*/
LIST *CreateList()
{
LIST *head,*pre,*cur;
int i,n;
head=NULL;
printf("輸入結點的個數:\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
cur=(LIST *)malloc(sizeof(LIST));
cur->next=NULL;
if(head==NULL)//表示處理當前第一個結點
head=cur;
else
pre->next=cur;
scanf("%d %s %s",&cur->num,&cur->name,&cur->address);
pre=cur;
}
return head;
} /*鏈表結點的插入*/
LIST *InsertNode(LIST *h,LIST *s)
{
LIST *pre,*p;
p=h;
if(h==NULL)
{
h=s;
s->next=NULL;

}
else
{
while(s->num>p->num&&p->next!=NULL)//在鏈表中找到要插入的位置
{
pre=p;
p=p->next;
}
if(s->num<=p->num)
{
if(h==p)//若插入的結點在第一個結點之前
{
h=s;
s->next=p;
}
else//若插入的結點在中間位置
{
s->next=p->next;
p->next=s;
}
}
else
{
p->next=s;
s->next=NULL;
}
}
return h;
}
/*鏈表結點的元素刪除*/
LIST *DeleteNode(LIST *h,long no)
{
LIST *q;
LIST *pre;
q=h;
if(q==NULL)
{
printf("鏈表為空,不能刪除結點\n");
return NULL;
}
while(q->num!=no&&q!=NULL)//查找帶刪結點,並保存其上一個結點
{
pre=q;
q=q->next;
}
if(q->num==no)
{
if(q==h)
{
h=h->next;
}
else
{
pre->next=q->next;
free(q);
printf("該結點被刪除成功!");
}
}
else
{
printf("在鏈表中無法找到該學號,刪除失敗!");
}
return h;
} /*完整的鏈表輸出*/
void Display(LIST *h)
{
LIST *q;
q=h;
while(q!=NULL)
{
printf("學號:%d 姓名:%s 地址:%s\n",q->num,q->name,q->address);
q=q->next;
}
} /**********************************NOTE*******************************
鏈表主要通過指針進行訪問,因此,他的地址不是連續的。因此, 鏈表無法實現隨機存儲,鏈表的元素查找,需要從頭結點開始逐 個掃描進行查找。鏈表是一種動態結構,相對於順序表而言,在 執行插入和刪除過程不需要移動大量的元素,執行效率大大提高。 以下就算法的四個基本操作進行總結。
鏈表的創建:(此處采用尾插法,並且鏈表元素有序)
1、定義四個指針*h,*rear,*cur,*p;分別代表頭指針,尾指針(指向 鏈表最後一個結點的指針),當前結點的指針,輔助指針
2、將頭指針指向NULL(此處為了統一所有操作,鏈表都帶有頭 結點 ,h=NULL,目的是建立一個全新的鏈表)
3、為全新的鏈表添加結點,由於是動態的,創建一個結點先要 申請內存,然後為其賦值,最後將其插入鏈表。由於鏈表的三個 部分(首部,尾部,中間)的不同,一般插入時要予以判斷, 進行不同操作。具體如下:(初始時p=h)
1)申請一個結點並初始化
cur=(LIST *)malloc(sizeof(LIST));
cur->next=NULL;
scanf("%d %s %s",&cur->num,&cur->name,&cur->address);//此步根據結點的定義來決定
2)插入鏈表
當鏈表為空時
if(h==NULL)
h=cur;
當鏈表不空時,通過某一參值比較,知道插入的位置(此處以num為參值)
while(p->num<cur->num&&p!=NULL)
p=p->next;
if(p==h)//當插入位置為第一個結點時
{
cur->next=h->next;
h=cur;
}
else if(p->next==NULL)//當插入位置為最後一個結點之後
{
p->next=cur;
cur->next=NULL;//可不要
}
else//當插入位置在中間時
{
cur->next=p->next;
p->next=cur;
}
插入完成,返回鏈表return h; 鏈表的插入:略,操作與鏈表的創建相同 鏈表的刪除:
查找與刪除,根據刪除的參值進行查找刪除元素前一個元素的位置(此處參值為num,前一元素指針*pre)
1)如果鏈表為空,則查找失敗,輸出提示信息
if(h==NULL)
printf("鏈表為空,查找失敗!\n")
else
{
while(p->num!=no&&p!=NULL)//查找待刪元素及其前一個結點的位置
{
pre=p;
p=p->next;
}
if(p->num==no)
{
if(p==h)//當待刪結點為第一個結點
h=pre->next;
else
pre->next=p->next;
}
else
printf("鏈表中不存在這個結點,刪除失敗!\n");
}
return h; 鏈表的輸出:
while(q!=NULL)
{
printf("學號:%d 姓名:%s 地址:%s\n",q->num,q->name,q->address);
q=q->next;
}

鏈表的創建,插入,刪除,輸出基本操作