問題:
????????單鏈表帶頭結(jié)點的創(chuàng)建以及輸出,以及帶與不帶頭節(jié)點的區(qū)別
思路:
- 單鏈表,邏輯上是線性結(jié)構(gòu),由許多單鏈表結(jié)點,串成一串。其單鏈表結(jié)構(gòu)體中,數(shù)據(jù)項由data數(shù)據(jù)域和結(jié)點指針域。
- 帶頭節(jié)點是為了使在空表時的操作更統(tǒng)一。如果不帶頭節(jié)點,空表插入時,直接讓頭指針,和第一節(jié)點指針相等即可。而非空表插入時,則時s->next=l->next;l->next=s;頭插,兩個操作。而帶上頭節(jié)點,所有情況下的插入操作,都同意了即都為s->next=l->next;l->next=s。
- 值得注意的是,帶頭節(jié)點的單鏈表,遍歷輸出時,記得從第二哥結(jié)點開始遍歷,即讓結(jié)點指針=頭指針的指針域。即snode*s =l->next;
- 在指針改變實際值時,C語言中,要么來哥雙指針,要么正常一維指針,最后返回頭指針,主函數(shù)內(nèi)接收即可。我覺得為了好理解,就用返回這個吧,整那么花里胡哨,也挺亂的。嗯
頭插法:
//創(chuàng)建帶頭節(jié)點的單鏈表
snode* sheadlist(snode* l,int n)
{
snode *phead=l;
phead=(snode*)malloc(sizeof(snode));//創(chuàng)建頭節(jié)點
phead->next=NULL;
int i=0,x=n,k=0;
printf("請輸入想要插入的值\n");
for(i=0;i<x;i++)
{
printf("輸入第%d個值\n",i+1);
scanf("%d",&k);
snode *p=(snode*)malloc(sizeof(snode));
p->data=k;
p->next=phead->next;
phead->next=p;
}
return phead;
}
尾插法:
//創(chuàng)建帶頭結(jié)點尾插法
linklist srearlist(linklist l,int x)
{
snode* phead=l;//創(chuàng)建頭節(jié)點
phead=(linklist)malloc(sizeof(snode));//用頭結(jié)點創(chuàng)造空間,指針l沒有創(chuàng)建,因此返回的時候返回頭節(jié)點 才能獲取整個單鏈表地址
phead->next=NULL;
int i,k;
snode *end=phead;//工作指針,從頭節(jié)點開始工作
printf("請輸入值\n");
for(i=0;i<x;i++)
{
scanf("%d",&k);
snode *p=(snode*)malloc(sizeof(snode));//創(chuàng)建新結(jié)點,用來尾插進單鏈表
p->data=k;
end->next=p;//直接給新結(jié)點連接起來
end=p; //因為尾插,所以要時刻知道最后一個結(jié)點的位置,因此s指針也跑到新加入的結(jié)點p上面.
}
end->next=NULL;
return phead;//頭節(jié)點始終指向整個單鏈表,因此返回頭節(jié)點地址,用來獲取整個字符串
}
按位查找,返回結(jié)點:
//返回第i個結(jié)點指針
snode* Searchnode(snode* phead,int i)
{
int count=1;//從有序數(shù)據(jù),數(shù)組第一個開始計算
snode* p=phead->next;
if(i==0) return phead;//返回頭節(jié)點
if(i<0) return NULL; //無效值
while(p!=NULL && count != i) //進行遍歷,每一次進行比對,每次遍歷指針后移
{
p=p->next;
count++;
}
return p;
}
按值查找,返回位置:(根據(jù)不同的情況需求在while判斷條件那里改變條件,進而求得想要的位置即可)
//按值查找,查找比x大的,并返回應(yīng)插入的位置
int Search_zhinode(snode* phead,int x)
{
snode* p=phead->next;
int count=1;
while(x>p->data)
{
p=p->next;
count++;
}
return count;
}
在某個位置插入一個結(jié)點:(按位查找的妙用:
(用按位查找找到第i-1個結(jié)點,通過這個結(jié)點,進行操作))
//在某個位置插入一個結(jié)點
snode* SInsert(snode* phead,int pos,int x)
{
if(pos<1 || pos>SLength(phead)) return NULL;
//進行插入操作
snode* p=(snode*)malloc(sizeof(snode));
p->data=x;
//獲取第pos-1個位置上的結(jié)點,在它后面插入
snode* ppre=Search_weinode(phead,pos-1);
p->next=ppre->next;
ppre->next=p;
return phead;
}
計算帶頭結(jié)點單鏈表長度:
//計算單鏈表長度
int SLenth(snode* phead)
{
if(phead==NULL) return 0;
int count=1;
snode* p =phead->next;//從有效數(shù)據(jù)第一個開始
while(p->next!=NULL)
{
p=p->next;
count++;
}
return count;
}
刪除第i個結(jié)點:(用按位查找找到第i-1個結(jié)點,通過這個結(jié)點,進行操作)
//刪除第i個結(jié)點
snode* SDelete(snode* phead,int i,int *x)
{
if(i<1 || i>SLenth(phead)) return NULL;
snode* p =Search_weinode(phead,i-1);
snode* q=p->next;
*x=q->data;
p->next=q->next;
free(q);
return phead;
}
?文章來源:http://www.zghlxwxcb.cn/news/detail-628943.html
代碼如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-628943.html
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//創(chuàng)建帶頭結(jié)點單鏈表
typedef struct snode
{
int data;
struct snode *next;
}snode,*linklist;
//創(chuàng)建帶頭節(jié)點的單鏈表
snode* sheadlist(linklist l,int n)
{
snode *phead=l;
phead=(snode*)malloc(sizeof(snode));//創(chuàng)建頭節(jié)點
phead->next=NULL;
int i=0,x=n,k=0;
printf("請輸入想要插入的值\n");
for(i=0;i<x;i++)
{
printf("輸入第%d個值\n",i+1);
scanf("%d",&k);
snode *p=(snode*)malloc(sizeof(snode));
p->data=k;
p->next=phead->next;
phead->next=p;
}
return phead;
}
//創(chuàng)建帶頭結(jié)點尾插法
linklist srearlist(linklist l,int x)
{
snode* phead=l;//創(chuàng)建頭節(jié)點
phead=(linklist)malloc(sizeof(snode));//用頭結(jié)點創(chuàng)造空間,指針l沒有創(chuàng)建,因此返回的時候返回頭節(jié)點 才能獲取整個單鏈表地址
phead->next=NULL;
int i,k;
snode *end=phead;//工作指針,從頭節(jié)點開始工作
printf("請輸入值\n");
for(i=0;i<x;i++)
{
scanf("%d",&k);
snode *p=(snode*)malloc(sizeof(snode));//創(chuàng)建新結(jié)點,用來尾插進單鏈表
p->data=k;
end->next=p;//直接給新結(jié)點連接起來
end=end->next; //因為尾插,所以要時刻知道最后一個結(jié)點的位置,因此s指針也跑到新加入的結(jié)點p上面.
}
end->next=NULL;
return phead;//頭節(jié)點始終指向整個單鏈表,因此返回頭節(jié)點地址,用來獲取整個字符串
}
//返回第i個結(jié)點指針
snode* Search_weinode(snode* phead,int i)
{
int count=1;
snode* p=phead->next;//從頭節(jié)點的后繼節(jié)點開始遍歷
if(i==0) return phead;
if(i<0) return NULL;
//遍歷,當值小于查找值時,一直遍歷,直到相等,count停止增加,此時便時所找位置處的結(jié)點,返回即可,
while(p!=NULL && count != i)
{
p=p->next;
count++;
}
return p;
}
//按值查找,查找比x大的,并返回應(yīng)插入的位置
int Search_zhinode(snode* phead,int x)
{
//默認單鏈表單調(diào)遞增,因此從頭遍歷的話,看誰比x大,便找到了,主要畫圖清楚
snode* p=phead->next;
int count=1;
while(x>p->data)
{
p=p->next;
count++;
}
return count;
}
void slprintf(snode *s)
{
if(s==NULL) return NULL; //空表 情況
snode *scan = s->next;//因為帶頭結(jié)點第一個結(jié)點為頭節(jié)點,所以打印從第二個結(jié)點打印,因此這里需要注意
while(scan != NULL)
{
printf("%d->",scan->data);
scan = scan->next;
}
printf("NULL\n");
}
//在某個位置插入一個結(jié)點
snode* SInsert(snode* phead,int pos,int x)
{
//進行插入操作
//創(chuàng)建需要插入的結(jié)點,給結(jié)點賦值
snode* p=(snode*)malloc(sizeof(snode));
p->data=x;
//獲取第pos-1個位置上的結(jié)點,在它后面插入
snode* ppre=Search_weinode(phead,pos-1);
//進行插入操作
p->next=ppre->next;
ppre->next=p;
return phead;
}
//計算單鏈表長度
int SLenth(snode* phead)
{
if(phead==NULL) return 0;
int count=1;
snode* p =phead->next;//從有效數(shù)據(jù)第一個開始
while(p->next!=NULL)
{
p=p->next;
count++;
}
return count;
}
//刪除第i個結(jié)點
snode* SDelete(snode* phead,int i,int *x)
{
//判斷插入合法性
if(i<1 || i>SLenth(phead)) return NULL;
//找到刪除結(jié)點的前驅(qū)結(jié)點
snode* p =Search_weinode(phead,i-1);//用按位查找,找到后返回前驅(qū)結(jié)點
//給q刪除,因此先讓q指針指向刪除結(jié)點,取出值,隨后p的指針域指向q的后繼節(jié)點,最后給q釋放。
snode* q=p->next;
*x=q->data;
//刪除操作
p->next=q->next;
free(q);
return phead;
}
int main()
{
//創(chuàng)建頭節(jié)點
snode* phead;
// phead=sheadlist(phead,3);
//尾插法建立帶頭節(jié)點單鏈表
phead=srearlist(phead,5);
//打印單鏈表
slprintf(phead);
// snode *p=Searchnode(phead,2);
//在有序的列表里面(默認有序),插入數(shù)值4,單鏈表仍有序
int pos=Search_zhinode(phead,4);
printf("pos=%d\n",pos);
//找到需要插入的位置后,進行在pos處的插入操作——即找到pos的前驅(qū)結(jié)點,之后進行插入
phead=SInsert(phead,pos,4);
slprintf(phead);
//計算單鏈表的長度
int len=SLenth(phead);
printf("單鏈表長度為%d\n",len);
//刪除第4個結(jié)點,并返回刪除結(jié)點的數(shù)值
int x=0;
phead=SDelete(phead,4,&x);//因為需要給刪除數(shù)值帶回來,所以給x的地址傳過去
printf("刪除了%d\n",x);
slprintf(phead);
return 0;
}
到了這里,關(guān)于7-數(shù)據(jù)結(jié)構(gòu)-(帶頭節(jié)點)單鏈表的增刪改查的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!