前言:
單鏈表這個結構,一定要理解鏈的意思,就是找到第一個才能 纔能找到第二個,不像陣列,想知道哪個數據,直接用下標就出來了,鏈表不允許這樣。強制性的必須知道第一個才能 纔能知道第二個,依次類推,這個想法要貫穿鏈表始終。
另外一個就是引入了指針這個概念,還有就是定義結構體的時候,看着程式碼會有點像遞回,我寫完後,試了試,其實就是遞回,可以一直點下去;我上網搜尋了一下,大概意思是有的編譯器會處理這個問題,這個其實不要太在意,就當是指向下一個數據元素的地址就行了,不要鑽牛角尖。
有什麼不對的可以直接說出來,我會修改
程式碼是C語言寫的,可以直接執行,效果就是下面 下麪的效果圖,程式碼可以單獨註釋,然後看單獨的效果,我是直接全部執行了。
程式碼看了一遍懂了,其實不算自己的,只有自己寫出來了,經過自己思考了,纔是自己的,並且寫的過程中也會加深理解概念。
效果圖:
#include <stdio.h>
#include <malloc.h>
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef struct Link //定義鏈表結點型別
{
ElemType data; //數據域
struct Link *next; //指針域
}Link,*LinkList;
/*頭插法建立一個單鏈表*/
LinkList HeadInitLink(Link *Lk)
{
Link *link;
Lk = (LinkList)malloc(sizeof(Link)); //建立頭結點
Lk->next=NULL;
int i = 1;
while(i<=10)
{
link = (LinkList)malloc(sizeof(Link));
link->data=i;
link->next=Lk->next;
Lk->next=link;
i++;
}
return Lk;
}
/*採用尾插法建立單鏈表*/
LinkList TailInitLink(Link *Lk)
{
Lk = (LinkList)malloc(sizeof(Link));
Link *link,*Tail=Lk;
int i = 1;
while(i<=10)
{
link = (LinkList)malloc(sizeof(Link));
link->data=i;
Tail->next=link; //link是一個地址
Tail=link; //link的地址給了Tail,然後就接着往下了,值並沒改變
i++;
}
Tail->next=NULL;
return Lk;
}
/*按序號查詢結點*/
LinkList GetLinkNode(Link *Lk,int i)
{
Link *p = Lk->next; //給頭節點的指針,也就是給個地址,開始順着地址查
if(i==0)
return Lk;
if(i<1)
return NULL;
int j = 1;
while(p && j<i)
{
p = p->next;
j++;
}
return p;
}
/*按值查詢表結點*/
LinkList ValueElemType(Link *Lk,ElemType e)
{
Link *p = Lk->next; //取頭結點指針域,開始查詢
while(p!=NULL && p->data!=e) //指針域不爲空,且數據域的值和要找的值不一樣,一樣的話就找到了
p=p->next;
return p;
}
/*求鏈表長度*/
int LenghtLink(Link *Lk)
{
Link *p=Lk->next;
int lenght = 0;
while(p)
{
p = p->next;
lenght++;
}
return lenght;
}
/*結點插入操作*/
LinkList InsertLink(Link *Lk,int i,ElemType e)
{
int lenght = LenghtLink(Lk);
if(i<1||i>lenght) //判斷插入位置是否合法
return NULL;
Link *pl,*p=Lk;
pl = (LinkList)malloc(sizeof(Link)); //生成新結點
int j = 1;
while(j<i)
{
p = p->next; //在要插入新結點之前;根據指針域地址不斷地找
j++;
}
pl->data=e;
pl->next=p->next;
p->next=pl;
return Lk;
}
/*結點刪除操作*/
LinkList DeleteLink(Link *Lk,int i)
{
int lenght = LenghtLink(Lk);
if(i<1||i>lenght) //判斷刪除位置是否合法
return NULL;
Link *dp,*p = Lk;
int j = 1;
while(j < i)
{
p = p->next;
j++;
}
dp = p->next; //p->next就是要刪除結點的後繼結點,很重要
p->next=dp->next;
free(dp); //free(C語言標準函數庫)
return Lk;
}
int main(void)
{
Link *Headlink,*Taillink,*Insertlink,*Deletelink,HeadLk,TailLk,InsertLk,DeleteLk;
Headlink = HeadInitLink(&HeadLk);
Headlink = Headlink->next;
printf("頭插法實現單鏈表\n");
while(Headlink)
{
printf("鏈表數據域的值爲:%d 鏈表指針域的值爲:%p\n",Headlink->data,Headlink->next);
Headlink=Headlink->next;
}
printf("\n");
Taillink = TailInitLink(&TailLk);
//按序號查詢結點值
printf("按序號查詢結點值\n");
int address = 6;
LinkList p = GetLinkNode(Taillink,address);
printf("第 %d 個結點數據域的值爲:%d;指針域的值爲:%p\n",address,p->data,p->next);
printf("\n");
printf("尾插法實現單鏈表\n");
Taillink = Taillink->next;
while(Taillink)
{
printf("鏈表數據域的值爲:%d 鏈表指針域的值爲:%p\n",Taillink->data,Taillink->next);
Taillink=Taillink->next;
}
printf("\n");
//在第6個結點位置插入一個新結點
printf("在第6個結點位置插入一個新結點\n\n");
int No = 666;
Insertlink = TailInitLink(&InsertLk);
Insertlink = InsertLink(Insertlink,address,No);
Insertlink = Insertlink->next;
while(Insertlink)
{
printf("新插入結點的鏈表數據域的值爲:%d 指針域的值爲:%p\n",Insertlink->data,Insertlink->next);
Insertlink=Insertlink->next;
}
printf("\n");
//刪除第6個結點
printf("刪除第6個結點\n\n");
Deletelink = TailInitLink(&DeleteLk);
int DeleteBefore = LenghtLink(Deletelink);
printf("刪除結點前鏈表長度:%d\n",DeleteBefore);
Deletelink = DeleteLink(Deletelink,address);
int DeleteAfter = LenghtLink(Deletelink);
printf("刪除結點後鏈表長度:%d\n",DeleteAfter);
Deletelink = Deletelink->next;
while(Deletelink)
{
printf("刪除結點後的鏈表數據域的值爲:%d 指針域的值爲:%p\n",Deletelink->data,Deletelink->next);
Deletelink=Deletelink->next;
}
printf("\n");
return 0;
}