1. 程式人生 > >單鏈表整表建立的兩種方法(頭插法和尾插法)

單鏈表整表建立的兩種方法(頭插法和尾插法)

線性表可分為順序儲存結構鏈式儲存結構

順序儲存結構的建立,其實就是一個數組的初始化,即宣告一個型別和大小的陣列並賦值的過程。而單鏈表和順序儲存結構就不一樣,它的每個資料的儲存位置不需要像陣列那樣集中,它可以很散,是一種動態結構。對於每個連結串列來說,它所佔用的空間大小和位置並不需要預先分配劃定,可以根據系統的情況和實際的需求即時生成。所以,建立單鏈表的過程就是一個動態生成連結串列的過程。即從“空表”的初始狀態起,一次建立各元素結點,並逐個插入連結串列。

單鏈表的整表建立

單鏈表的整表建立主要有兩種方法,即頭插法和尾插法,下面分別對這兩種方法進行介紹

頭插法建立單鏈表(含有頭結點)

頭插法建立單鏈表的步驟:

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這一句程式碼,它的作用是:只要新結點插入進去了,那麼他就會變成尾部結點。然後不斷重複這個操作。流程如下:

尾插法建立單鏈表結果展示:


顯然尾插法建立的連結串列是正序的