資料結構總結 單鏈表 迴圈鍊錶 雙向鍊錶

2021-07-02 19:38:48 字數 3608 閱讀 6759

總體構成:

頭節點:不作資料的儲存,儲存鍊錶的公共資料資訊,如:長度;另外還有,還包括頭指標,指向第乙個資料節點;

資料節點:顧名思義是存資料的,鍊錶最後的節點的指標域為null;

節點的構成:

資料域:儲存資料元素資訊

操作流程:

遍歷的流程

1. 通過頭節點的指標域得到第乙個元素

2. 在通過第乙個元素的資料域得到第乙個元素的資料,通過第乙個元素的指標域得到第二個元素;

3. 以此類推,

4. 直到得到目標元素或最後最後乙個節點為止;

新增流程

1. 根據遍歷的流程,查詢到要新增的節點的位置;

2. 宣告乙個新節點,新元素新增到該新節點中;

3. 將此位置後面元素的指標,新增到新節點後面(即:新節點的指標域中);

4. 將新節點的指標,新增到此位置前面元素的指標域;

刪除流程

1. 根據遍歷的流程,查詢到要刪除的節點的位置;

2. 取出刪除的節點後面所有元素(下面稱為:afternodes);

3. 將afternodes的指標賦值給刪除節點前一元素節點的指標域;

4. 釋放刪除元素的記憶體;

優勢與缺點:

對於所謂的優勢與劣勢,都是對比出來的,在此我們拿順序儲存結構來比較:

讀取時:

並沒有優勢,因為首先需要遍歷鍊錶,找到需要讀取的節點的位置;時間複雜度為o(n),

而順序儲存結構,可直接使用下標,其時間複雜度為o(1);

新增和刪除:

單鏈表:也是要遍歷後才得到新增或者刪除的位置後(時間複雜度為o(n),才進行新增刪除操作(時間複雜度為o(1));

順序儲存結構:移動元素,時間複雜度為o(n);

個人見解:綜合起來兩者效能沒有太大區別,

如果新增刪除操作頻繁時,單鏈表效能就體現出來了,

如果無法預知長度,單鏈表也是也是比較好的選擇!

#include

#include

#define maxsize 20

#define ok 1

#define error 0

#define

true

1#define

false

0typedef int status;

typedef int elemtype;

typedef struct node

node;

typedef node *linklist;

// status getelem(linklist l, int i, elemtype *e)

if (!p || j > i)

*e = p->

data; // 取出第i個節點的資料

return ok;

}// 頭插法

void createlisthead(linklist *l, int n)

}// 尾插法

void createlisttail(linklist *l, int n)

r->next =

null;

}// 清除鍊錶

status clearlist(linklist *l)

(*l)->next =

null;

return ok;

}// 在我們不知道第i個節點的指標位置時,

// 單鏈表資料結構在插入和刪除操作上,

// 與線性表的順序結構是沒有太大的優勢的;

// 但是,在第i個位置插入10個節點時,

// 線性表的順序結構在每次插入時都需要移動n-i個節點,時間複雜度為o(n)

// 單鏈表,在找到i的位置後,只要簡單的通過賦值移動指標而已,時間複雜度為o(1)

// 在這裡,單鏈表的優勢才體現出來。

status listinsert(linklist *l, int i, elemtype e)

if (!p || j > i)

return error; // i節點不存在

s = (linklist)malloc(sizeof(node));

s->

data

= e;

s->next = p->next;

p->next = s;

return ok;

} status listdelete(linklist *l, int i, elemtype *e)

if (!p->next || j > i)

return error;

q = p->next;

p->next = q->next;

*e = q->

data;

free(q);

return ok;

}

迴圈鍊錶

與單鏈表不同的就是尾節點的區別而已,尾節點指向頭節點,其他均相同;

void createlist(dulinklist *l, int n)

r->next = *l; // (迴圈鍊錶新增加)尾節點指向頭節點

}

雙向鍊錶

與單鏈表的不同也不大,結構如下:

typedef

struct dulnode

dulnode, *dulinklist;

相比單鏈表的後繼,多了前驅的操作(prev),**如下:

status listinsert(dulinklist *l, int i, elemtype e)

if (!p || j > i)

return error; // i節點不存在

s = (dulinklist)malloc(sizeof(dulnode));

s->

data

= e;

s->prev = p; // 把p賦值給s的前驅

s->next = p->next; // 把p->next賦值給s的後繼

p->next->prev = s; // 把s賦值給p->next的前驅

p->next = s; // 把s賦值給p的後繼

return ok;

} status listdelete(dulinklist *l, int i, elemtype *e)

if (!p->next || j > i)

return error;

q = p->next;

*e = q->

data;

//p->next = q->next; // 單鏈表

p->prev->next = p->next; // 把p->next賦值給p->prev的後繼

p->next->prev = p->prev; // 把p->prev賦值給p->next的前驅

free(q);

return ok;

}

資料結構 雙向迴圈鍊錶

近期我在學習資料結構,於是我自己整理了單鏈表 迴圈單鏈表 雙向鍊錶 雙向迴圈鍊錶的相關 以鞏固這段時間的學習,也希望能夠幫助初學者,希望大家在閱讀以下 時發現問題糾正於我,一起 cycdoublelist.h ifndef cycdoublelish h define cycdoublelish h...

資料結構 雙向迴圈鍊錶

typedef struct node node,pnode pnode init dc list void 雙向迴圈鍊錶的初始化 pnode new node int dat 新建乙個節點 把位址為pnew的節點插入到雙向迴圈鍊錶的尾部 頭節點的前面 bool list add tail pnod...

資料結構 雙向鍊錶,迴圈鍊錶

也許是自己太小看資料結構,練習了幾天還在第二章徘徊,可自己覺得基礎還是要打牢的好 總結一下 第乙個是雙向鍊錶,include include typedef struct node node,linklist void creat linklist l else int insert linklis...