數據結構——線性表

一、線性表

這篇總結的主要是線性表的知識點,可以收藏下來,哪些地方概念不是特別清楚的時候翻出來看看。如果想看本章涉及到的代碼部分,見文章下方超鏈接。

另外有些地方序號可能排版比較亂,之前在Typora上寫的,導入過來之後貌似排序受到了影響,希望不影響閱讀。

(一)線性表的下定義和基本操作
  1. 定義:

    • 線性表是具有相同特性數據元素的一個有限序列。該序列中所含元素的個數叫做線性表的長度,用n(n>=0)表示,n=0表示線性表是一個空表。
    • 另外一個數據元素也可以由若干個數據項組成,在這種情況下,常把數據元素稱爲記錄。例如:表格中的一行的數據項:姓名,性別,電話等,含有大量記錄的線性表稱爲文件。
  2. 邏輯特性:

    • 只有一個表頭元素,只有一個表尾元素,表頭元素沒有前驅,表尾元素沒有後繼,除了表頭,表尾外,其他元素只有一個直接前驅和一個直接後繼。
  3. 存儲結構:

    • 順序存儲結構----順序表
    • 鏈式存儲結構----鏈表
  4. 基本操作:

    /******************************部分代碼實現如上方超鏈接*********************************/
    - Initlist(&L)					        	//構造一個空的線性表L
    - DestoryList(&L)                       	//銷燬線性表L
    - ClearList(&L)                            	//將線性表L重置爲0
    - ListEmpty(L)                             	//判斷線性表是否爲空 
    - ListLength(L)                            	//返回線性表L的數據元素個數
    - GetElem(L,i,&e)                          	//用e來返回線性表L中第i個數據元素
    - LocateElem(L,e,compare())    				//返回L中與e滿足關係的數據元素的位序
    - PriorElem(L,cur_e,&pre_e)     			//用pre_e返回cur_e的前驅
    - NextElem(L,cur_e,&next_e)    				//用next_e返回cur_e的後繼
    - ListInsert(&L,i,e)                       	//在L中的第i個位置插入新的數據元素e
    - ListDelete(&L,i,&e)                   	//刪除L中的第i個元素,用e返回其值
    - ListTraverse(L,visit())                	//對L中的每個元素調用函數visit()             
    
(二)線性表的實現
  1. 順序存儲

    • 順序存儲就是把線性表中的所有元素按照其邏輯順序依次存儲到指定的存儲位置開始的一塊連續的存儲空間中。

    • 優點:

      • 可以隨機訪問數組中的元素——隨機訪問特性
      • 邏輯相鄰,物理相鄰——佔有連續的存儲空間
      • 存儲空間使用緊湊——存儲空間利用率高
    • 缺點:

      • 插入,刪除需要移動大量元素
      • 預先分配空間需要按照最大使用空間分配,利用不充分
      • 表容量難以擴充
    • 核心代碼

      #define MAX_SIZE 30				//設置順序表最大容量
      typedef struct
      {
      	int data[MAX_SIZE];			//設置數據最大長度
      	int length;					//設置數據當前長度
      
      }Sqlist;
      
  2. 鏈式存儲

    • 鏈式存儲中,每個結點不僅包含所存元素的信息,還包含元素之間邏輯關係的信息

    • 優點:

      • 動態分配內存空間
      • 插入,刪除無需移動元素
      • 由於內存是隨機分配的,使得數據刪除後覆蓋率低,恢復可能提高
    • 缺點:

      • 不支持隨機訪問,
      • 查找節點時,鏈式存儲比順序存儲慢
      • 比順序存儲結構的存儲密度稍小——存儲空間利用率比較低
    • 鏈表的5種表現形式

      • 單鏈表

        • 每個結點種不僅除了包含數據域外,還包含一個指針域,用以指向其後繼結點。

        • 核心代碼

          typedef struct LNODE
          {
          	int data;						//數據域
          	struct LNODE* next;				//指針域
          }LNODE;
          
        • 圖形所示,便於理解

        [外鏈圖(img-WAKEpbEF1564582507551)(C:\Users\DONG\AppData\RoDTaming\eypora\typora-usimages\r56458484127120C.png:\Users\DONG\AppData\Roaming\Typora\typora-user-images\1564581248420.png)(C:\Users\DONG\AppData\Roaming\Typora\typora-user-images\1564581248420.png)]

        • 這裏順便說一下頭結點,也就是上圖看到的Head指針的這個結點。
          • 帶頭結點的單鏈表中,頭指針Head指向頭結點,頭結點數據域不包含任何信息,從頭結點的後繼結點開始存放數據信息。頭指針Head始終不等於NULL,head->next 等於NULL說明鏈表爲空
          • 不帶頭結點的單鏈表中,頭指針Head指向開始結點,當head等於NULL的時候,鏈表爲空。
      • 雙鏈表

        • 由於單鏈表只能從開始結點走到終端結點,不能返回。因此雙鏈表就是爲了解決這種問題的。雙鏈表在單鏈表的基礎上增添了一個指針域,指向當前結點的前驅。

        • 核心代碼

          typedef struct DLNODE
          {
          	int data;							//存放結點中的數據
          	struct DLNODE *prior;				//指向前驅結點的指針
          	struct DLNODE* next;				//指向後繼結點的指針
          }DLNODE;
          
        • 圖形所示

          在這裏插入圖片描述

        • 循環單鏈表

          • 循環單鏈表:只要將單鏈表的最後一個結點的指針域指向鏈表中的第一個結點即可。
        • 循環雙鏈表

          • 循環雙鏈表:將雙鏈表的最後一個結點next的指針域指向鏈表的第一個結點,並且鏈表第一個結點的指針域prior指向最後一個結點。
        • 靜態鏈表

          • 藉助一維數組實現,數組中的每一個結點含有兩個分量:一個是數據元素data,另一個是指針分量,指向當前結點的直接後繼在數組中的位置,即下標。
          • 圖形所示
            • [外鏈圖片轉存失敗(img-INQczhkC-1564582507559)(C:\Users\DONG\AppData\Roaming\Typora\typora-user-images\1564581463498.png)]
  3. 線性表的應用

    • 基本操作:增刪查改
    • 合併兩個鏈表或者順序表等。
(三)本章相關代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章