新技術新方法的產生都是為了實際遇到的問題,單鏈表的出現也是為了解決順序表在某些方面的不足,比如順序表的插入和刪除都需要移動大量的元素。
首先了解一下單鏈表的定義:為了表示每個資料元素與其直接後繼元素之間的邏輯關係 , 每個元素除了儲存本身的資訊外 , 還需要儲存指示其直接後繼的資訊 。
單鏈表的一些基本概念:
表頭結點: 鍊錶中的第乙個結點 , 包含指向第乙個資料元素的指標以及鍊錶自身的一些資訊;
資料結點:鍊錶中代表資料元素的結點 , 包含指向下乙個資料元素的指標和資料元素的資訊;
尾結點:鍊錶中的最後乙個資料結點 , 其下一元素指標為空 , 表示無後繼。
同樣我們要實現以下單鏈表的操作
linklist* linklist_create();
void linklist_destroy(linklist* list);
void linklist_clear(linklist* list);
int linklist_length(linklist* list);
int linklist_insert(linklist* list, linklistnode* node, int pos);
linklistnode* linklist_get(linklist* list, int pos);
linklistnode* linklist_delete(linklist* list, int pos);
在c語言中可以用結構體來定義鍊錶中的指標域,鍊錶中的頭結點也可以用結構體實現,以下是linklist.h中的結構體定義
typedef void linklist;
typedef struct _tag_linklistnode linklistnode; // 定義包含指標域的結構體
struct _tag_linklistnode
;
linklist.c檔案中頭結點結構體定義
// 定義表頭結點,同時需要包含指標域的結構體(頭結點包含的資訊是長度和指向第乙個結點的指標)
typedef struct _tag_linklist
tlinklist;
1、單鏈表的建立函式
linklist* linklist_create() // o(1)
return ret;
}
注意在建立時進行初始化,頭結點要指向null,並且長度要賦值為0。
2、單鏈表的銷毀、清除以及長度獲取函式
void linklist_destroy(linklist* list) // o(1)
void linklist_clear(linklist* list) // o(1)
}int linklist_length(linklist* list) // o(1)
return ret;
}
其中銷毀和清除是兩種操作,銷毀意味著清除所有鍊錶中的元素,並且**建立時申請的堆空間;而清除則只是將乙個線性表list中的所有元素清空,使得線性表回到建立時的初始狀態。
3、單鏈表的插入操作
int linklist_insert(linklist* list, linklistnode* node, int pos) // o(n)
node->next = currnent->next; // current->next 包含了為null的情況
currnent->next = node;
slist->length++;
} return ret;
}
插入操作首先要進行合法性的判斷,包括線性表是否合法,插入位置是否合法;
插入的位置為由表頭開始通過next指標移動pos次後,當前元素next指標指向的位置,這裡將這個指標定義為current;
這裡不需要區分插入的位置是鍊錶中還是鍊錶尾,在**實現上是一樣的,如果不能理解可以畫圖實際操作一下就能一目了然了。
4、單鏈表的獲取函式
linklistnode* linklist_get(linklist* list, int pos) // o(n)
// current指向頭結點,分析若pos=0,for迴圈不執行,則current->next指向下標為0的元素,也就是第乙個元素
ret = currnent->next; // 畫圖可以解決所有問題
} return ret;
}
單鏈表的獲取操作也是通過表頭指標的移動來實現的,表頭開始通過next指標移動pos次後,當前元素next指標指向的位置,這裡將這個指標定義為current。
5、單鏈表的刪除函式
linklistnode* linklist_delete(linklist* list, int pos) // o(n)
ret = currnent->next; // current->next 就是要刪除的結點,所以賦值給ret用作返回值
currnent->next = ret->next;
slist->length--;
} return ret;
}
這個函式的實現是利用current指標的移動,然後按照下圖一步操作就可以實現刪除操作。
總結:我們可以發現頭指標非常重要,單鏈表所有的操作都是基於頭指標來的;另外我認為學習資料結構很重要的乙個方法就是畫圖,資料的組織有時候很抽象,如果單憑想象去構建這樣一幅圖很容易出錯,所以乙個筆一張紙就可以讓問題變得簡單明瞭。可以看出單鏈表非常順利的解決了順序表插入和刪除需要移動大量元素的問題。
單鏈表的優缺點:
優點:(1)無需一次性定製鍊錶的容量;
(2)插入和刪除操作無需移動資料元素
缺點:(1)0資料元素必須儲存後繼元素的位置資訊;
(2)獲取指定資料的元素操作需要順序訪問之前的元素
線性表的鏈式儲存結構 單鏈表
線性表中每個節點有唯一的前趨節點和後繼節點 每個 物理節點增加乙個指向後繼節點的指標域 單鏈表 每個物理節點增加乙個指向後繼節點和前趨節點的指標域 雙鏈表 單鏈表的特點 當訪問乙個節點後,只能接著它的後繼節點,而無法訪問它的前趨節點。1.單鏈表插入節點 操作 將值為x的新節點 s插入到 p節點之後 ...
線性表的鏈式儲存結構之單鏈表
void initlist list plist 初始化 plist next null 2 插入元素 insert 1 宣告結點p指向鍊錶第乙個結點 2 當p null時,就遍歷鍊錶,讓p的指標向後移動,不斷指向下乙個結點,i 3 若到鍊錶末尾p為空,則說明第i個元素不存在 4 否則查詢成功,在系...
線性表的鏈式儲存結構及實現 單鏈表
單鏈表是用一組任意的儲存單元存放線性表的元素,這組儲存單元可以連續也可以不連續。template typename t struct node template class t class linklist linklist t a,int n linklist int length t get i...