嘗試了一下用鏈表存儲(chǔ)學(xué)生學(xué)號(hào)成績數(shù)據(jù),從中還是遇到很多問題榴捡。
最初杈女,刪除節(jié)點(diǎn)的時(shí)候,我是不準(zhǔn)備返回地址的
一開始是這樣寫刪除的:
void stu_result *delet(struct stu_result *head,int i)
{
int j;
if(i==1)
{
head=head->next;
}
else
{
for(j=0;j<i-2;j++)/**************************************************************************
j<i-2是控制循環(huán)到需刪除的節(jié)點(diǎn)的前一個(gè)地址
(比如要?jiǎng)h除第2個(gè)節(jié)點(diǎn)他就不會(huì)進(jìn)入循環(huán)因?yàn)閔ead就是第2個(gè)節(jié)點(diǎn)的前一個(gè)吊圾,而如果要?jiǎng)h除第3個(gè)節(jié)點(diǎn)時(shí)他就進(jìn)行一次)
********************************************************************************************************/
{
head=head->next;
}
head->next=head->next->next;
}
}
如果刪除的不是第一個(gè)節(jié)點(diǎn)當(dāng)然沒什么問題达椰,但當(dāng)刪除第一個(gè)節(jié)點(diǎn)時(shí),原來的鏈表是以頭地址傳輸?shù)?原來的鏈表并沒有改變项乒,所以當(dāng)刪除第一個(gè)節(jié)點(diǎn)時(shí)要返回一個(gè)新的鏈表頭地址覆蓋原來的鏈表啰劲。
完整正確的代碼如下:
#include<stdio.h>
struct stu_result
{
int num;
float score;
struct stu_result *next;
};
struct stu_result *build();//創(chuàng)建鏈表
void prinf(struct stu_result *head);//輸出鏈表
struct stu_result *delet(struct stu_result *head,int a);//鏈表的節(jié)點(diǎn)刪除
int main()
{
int i;//i為需要?jiǎng)h除的第幾個(gè)鏈表元素
struct stu_result *stu;
stu=build();
printf("\n\n\n");
prinf(stu);
printf("您需要更改刪除鏈表元素嗎,如需要請(qǐng)輸入鏈表第幾個(gè)節(jié)點(diǎn)板丽!\n");
scanf("%d",&i);
stu=delet(stu,i);
printf("\n\n");
prinf(stu);
}
struct stu_result *build()
{
int n;//指創(chuàng)建到第幾個(gè)節(jié)點(diǎn)
struct stu_result student[100],*head,*p1,*p2
/*我利用數(shù)組來建立鏈表呈枉,也可以用malloc函數(shù)來建立鏈表 :"p1=(struct stu_result)malloc(sizeof(stu_result));"
p1和p2是方便用來指向新創(chuàng)建的節(jié)點(diǎn)的*/
p1=p2=&student[0];//p1,p2先初始化指向第一個(gè)節(jié)點(diǎn)
head=NULL;//初始化
printf("請(qǐng)輸入學(xué)號(hào)(0結(jié)束):") ;
scanf("%d",&p1->num);
for(n=0;p1->num!=0;)//判斷是否輸入0,是否應(yīng)該創(chuàng)建下一個(gè)節(jié)點(diǎn)
{
n=n+1;
if(n==1)//進(jìn)行首次的節(jié)點(diǎn)創(chuàng)建(之后就用不著了)
{
head=p1;//head指向第一個(gè)節(jié)點(diǎn)
}
else//再次的指向新創(chuàng)建的節(jié)點(diǎn)
{
p2->next=p1;
}
printf("請(qǐng)輸入分?jǐn)?shù):");
scanf("%f",&p1->score);
p2=p1;//(首次節(jié)點(diǎn)創(chuàng)建時(shí)用不著),從第二次后開始埃碱,p2與p1同步指向新節(jié)點(diǎn)
p1=&student[n];//開辟新節(jié)點(diǎn)
printf("請(qǐng)輸入學(xué)號(hào)(0結(jié)束):");
scanf("%d",&p1->num);
}
p2->next=NULL;//結(jié)束最后一個(gè)節(jié)點(diǎn)猖辫,指向NULL
return head;//返回鏈表
}
void prinf(struct stu_result *head)
{
printf("\n\n");
while(head!=NULL)
{
printf("學(xué)號(hào)是%d\n",head->num);
printf("分?jǐn)?shù)是%f\n",head->score);
head=head->next;
printf("\n");
}
}
struct stu_result *delet(struct stu_result *head,int i)
{
int j;
struct stu_result *newstu;//新鏈表
struct stu_result *p;//用來替換初始的head,方便返回原鏈表
p=head;
if(i==1)
{
p=p->next;
newstu=p;
return newstu;/************************
因?yàn)榈谝粋€(gè)節(jié)點(diǎn)改變了(最初的sut鏈表中的head改變)
所以他的頭地址必須更新,返回一個(gè)新的頭地址鏈表
***********************/
}
else
{
for(j=0;j<i-2;j++)/**************************************************************************
j<i-2是控制循環(huán)到需刪除的節(jié)點(diǎn)的前一個(gè)地址
(比如要?jiǎng)h除第2個(gè)節(jié)點(diǎn)他就不會(huì)進(jìn)入循環(huán)因?yàn)閔ead就是第2個(gè)節(jié)點(diǎn)的前一個(gè)砚殿,而如果要?jiǎng)h除第3個(gè)節(jié)點(diǎn)時(shí)他就進(jìn)行一次)
********************************************************************************************************/
{
p=p->next;
}
p->next=p->next->next;
return head;
/**********************
第一個(gè)節(jié)點(diǎn)沒有改變(head不變),
根據(jù)鏈表的性質(zhì)啃憎,指向下一個(gè)節(jié)點(diǎn)的地址。
所以返回原來的鏈表即可似炎,無需返回新的鏈表
**********************************/
}
}
鏈表.jpg