單鏈表整表建立的兩種方法(頭插法和尾插法)
阿新 • • 發佈:2019-01-01
線性表可分為順序儲存結構和鏈式儲存結構
順序儲存結構的建立,其實就是一個數組的初始化,即宣告一個型別和大小的陣列並賦值的過程。而單鏈表和順序儲存結構就不一樣,它的每個資料的儲存位置不需要像陣列那樣集中,它可以很散,是一種動態結構。對於每個連結串列來說,它所佔用的空間大小和位置並不需要預先分配劃定,可以根據系統的情況和實際的需求即時生成。所以,建立單鏈表的過程就是一個動態生成連結串列的過程。即從“空表”的初始狀態起,一次建立各元素結點,並逐個插入連結串列。
單鏈表的整表建立
單鏈表的整表建立主要有兩種方法,即頭插法和尾插法,下面分別對這兩種方法進行介紹
頭插法建立單鏈表(含有頭結點)
頭插法建立單鏈表的步驟:
1. 宣告一指標變數p和計數器n;
2. 初始化一空連結串列L;
3. 讓L的頭結點的指標指向NULL,即建立一個帶頭結點的單鏈表;
4. 迴圈:
- 生成一新結點賦值給p;
- 隨機生成一個數字賦值給p的資料域;
- 將p插入到頭結點與前一新結點之間。
頭插法實現的程式碼如下:
#include<stdio.h> #include<malloc.h> #include<time.h> #include<stdlib.h> struct node //建立結構體 { int data; //elementype表示一種資料型別,可能是int/char等等 struct node *next; //next 指標,用於連結串列結構指向下一個節點 }; typedef struct node node; //重定義struct node型別為node node* Creat(int Count) //建立連結串列 { node *p,*head; int n; srand(time(NULL)); //生成種子 head = (node*)malloc(sizeof(node)); head->data = Count; head->next = NULL; //頭結點儲存連結串列長度 for (n = 0;n < Count;n++) { p = (node*)malloc(sizeof(node)); p->data = rand()%1000; p->next = head->next; //頭插法單鏈表建立的關鍵兩行程式碼 head->next = p; } return(head); } void List(node* head) //列印連結串列 { node *p1; p1 = head; while(p1!= NULL) { printf("%4d",p1->data); p1 = p1->next; } } int main() //主函式 { node* head; int Num; printf("Enter the number of linked list nodes:\n"); scanf("%d",&Num); head = Creat(Num); printf("\n"); printf("List:\n"); List(head); printf("\n"); }
這段演算法程式碼中,我們其實用的是插隊的辦法,就是始終讓新結點在第一的位置。如下圖所示:
每一個新結點都插在頭結點之後的位置,所謂插入,實際上就是為新建立的結點解決兩個問題:它指向誰和誰指向它,在程式碼中分別由
p->next = head->next; //新結點指向原來頭結點的後面一個結點
head->next = p; //頭結點指向新結點
這兩句程式碼解決了這兩個問題,那麼連結串列的建立也就完成了。由於始終讓新結點處在第一的位置,所以這種方法稱為頭插法。
頭插法建立單鏈表結果展示:
這種方法雖然實現了連結串列的建立,由於是頭插,所以連結串列的順序是逆序的,下面介紹的尾插法建立的連結串列的順序是正序的。
尾插法建立單鏈表
#include<stdio.h>
#include<malloc.h>
#include<time.h>
#include<stdlib.h>
struct node //建立結構體
{
int data; //elementype表示一種資料型別,可能是int/char等等
struct node *next; //next 指標,用於連結串列結構指向下一個節點
};
typedef struct node node; //重定義struct node型別為node
node* Creat(int Count) //建立連結串列
{
node *p1,*p2,*head;
int n;
srand(time(NULL));//生成種子
head = p1 = (node*)malloc(sizeof(node)); //p1為指向表尾結點的指標
head->data = rand()%1000;
head->next = NULL;
for (n = 1;n < Count;n++)
{
p2 = (node*)malloc(sizeof(node)); //p2為新申請的結點
p2->data = rand()%1000;
p1->next = p2; //將表尾結點的指標指向新結點
p1 = p2; //將當前的新結點定義歲表尾終端節點
}
p1->next = NULL; //迴圈結束後最終的尾結點的指標賦值為NULL
return(head);
}
void List(node* head) //列印連結串列
{
node *p1;
p1 = head;
while(p1!= NULL)
{
printf("%4d",p1->data);
p1 = p1->next;
}
}
int main() //主函式
{
node* head;
int Num;
printf("Enter the number of linked list nodes:\n");
scanf("%d",&Num);
head = Creat(Num);
printf("\n");
printf("List:\n");
List(head);
printf("\n");
}
在這個演算法中,每次新申請的結點都插入到了表尾,所以稱為尾插法,注意理解p1=p2這一句程式碼,它的作用是:只要新結點插入進去了,那麼他就會變成尾部結點。然後不斷重複這個操作。流程如下:
尾插法建立單鏈表結果展示:
顯然尾插法建立的連結串列是正序的