數據結構——線性表學習總結2(單鏈表實現)

前言:每週儘量寫一篇博客,貴在堅持,同時也是一次很好的複習和鞏固;本篇博客主要總結線性表的鏈式存儲結構,在理解概念的同時我參照CSDN論壇大佬的程序寫了“自己”的第一個單鏈表,實踐一遍真的會搞懂蠻多的細節,下面開始正文(筆記來源小甲魚視頻):

一、線性鏈表的特點和邏輯結構
1、特點:考慮到順序表插入和刪除操作需要移動大量的元素,線性鏈表可以不連續存儲,原本由數組相對存儲空間所規定的兩個元素的關係,現在由鏈表的指針所代替,理解這裏指針所起的關鍵作用至關重要。

2、邏輯結構
L鏈表的圖解
如上圖,一個鏈表由不必在內存中相連的結構構成;每一個結構包含表元素和指向該元素後繼結構的指針。該指針被稱爲Next指針,最後一個Next指針指向NULL;

該結構叫做結點(Node):由數據域和指針域構成

  • 數據域:存儲數據元素信息的域;
  • 指針域:存儲後繼位置的域;

3、頭節點和頭指針
1

如圖,L指向的結點即爲頭結點,L即爲頭指針

  • 頭指針是鏈表指向第一個結點的指針;
  • 頭指針具有標識作用;(常用頭指針來命名鏈表)
  • 無論鏈表是否爲空,頭指針均不爲空;
  • 頭指針是鏈表的必要元素;

頭節點

  • 爲了操作的統一和方便設立,放在第一個元素的結點之前,數據域無意義;
  • 有了頭節點,對在第一個元素結點前插入結點和刪除第一個結點,其操作就統一了;
  • 頭結點不一定是鏈表要求;
  • 其數據域一般存儲鏈表的長度N;

二、線性鏈表的常見操作

1、線性鏈表用結構指針描述

typedef int ElemType;
//定義結點類型 
typedef struct Node
{
    ElemType data;               //單鏈表中的數據域 
    struct Node *next;           //單鏈表的指針域 
}Node,*LinkedList;

2、單鏈表的初始化

//1、單鏈表的初始化
LinkedList Init_Linklist()
{
    Node *L;
    L = (Node *)malloc(sizeof(Node));   //申請結點空間 
    if(L == NULL)                       //判斷是否有足夠的內存空間 
        printf("申請內存空間失敗\n");
    L->next = NULL;                   //將next設置爲NULL,初始長度爲0的單鏈表 
}

2、單鏈表的建立,包含頭插法和尾插法

//2、單鏈表的建立,頭插法建立單鏈表
LinkedList Create_head_Linklist()
{
    Node *L;
    L = (Node *)malloc(sizeof(Node));   	//申請頭結點空間
    L->next = NULL;                       //初始化一個空鏈表
    ElemType x;                        	 //x爲鏈表數據域中的數據
    while(scanf("%d",&x))
    {
		if(x == 0)
				break;                   //設置0爲中止符
        Node *p;
        p = (Node *)malloc(sizeof(Node));   //申請新的結點 
        p->data = x;                     	//結點數據域賦值 
        p->next = L->next;                     //將結點插入到表頭
        L->next = p; 
    }
    return L; 
} 
 
//3、單鏈表的建立,尾插法建立單鏈表
LinkedList Create_tail_Linklist()
{
    Node *L;
    L = (Node *)malloc(sizeof(Node));   //申請頭結點空間
    L->next = NULL;                  	 //初始化一個空鏈表
    Node *r;
    r = L;                          	 //r始終指向終端結點,開始時指向頭結點 
    ElemType x;                         //x爲鏈表數據域中的數據
    while(scanf("%d",&x))
    {
		if(x == 0)
			break;
        Node *p;
        p = (Node *)malloc(sizeof(Node));   //申請新的結點 
        p->data = x;                    	 //結點數據域賦值 
        r->next = p;                		 //將結點插入到表尾 
        r = p; 
    }
    r->next = NULL; 
     
    return L;   
}

3、單鏈表的插入,在鏈表的第i個位置插入x的元素
2
關鍵操作:

p->next = pre->next;//把pre所指向的傳遞給p
pre->next = p;//把指向p的指針給pre,即pre現在指向了新結點p
LinkedList Insert_Linklist(LinkedList L,int i,ElemType x)
{
    Node *pre;                      				 //pre爲前驅結點 
    pre = L;
    int temp = 0;
    for (temp = 1; tempi < i; temp++)
        pre = pre->next;                			 //查找第i個位置的前驅結點 
    Node *p;                               			  //插入的結點爲p
    p = (Node *)malloc(sizeof(Node)); 
    p->data = x; 
    p->next = pre->next;
    pre->next = p;
    return L;                           
} 

4、單鏈表的刪除,在鏈表中刪除值爲x的元素
在這裏插入圖片描述
關鍵操作:

pre-next = p->next;//即pre->next = pre->next->next;逃過了pre-next,x相當於刪除了
LinkedList Delete_Linklist(LinkedList L,ElemType x)
{
    Node *p,*pre;                  				 //pre爲前驅結點,p爲查找的結點。 
    p = L->next;
    while(p->data != x)              			 //查找值爲x的元素 
    {   
        pre = p; 
        p = p->next;
    }
    pre->next = p->next;          				 //刪除操作,將其前驅next指向其後繼。 
    free(p);
    return L;
} 

5、整表刪除

/*單鏈表的整表刪除*/
 Clear_LinkList(LinkedList *L)
{
	Node *p, *pre;     //pre爲前驅,p爲中轉
	pre = L->next;
	while(pre)
	{
		p = pre->next;
		free(pre);
		pre = p;
	}
	
	L->next =NULL;
	return L;
  }  

抓住主要矛盾,搞清楚指針的操作原理是理解的關鍵;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章