我們最早學習的線性表分為順序表和煉表,順序錶即用陣列來模擬鍊錶,他的記憶體是連續的;缺點在於事先要知道大小,但是實際生活中我們並不能實現準確的預知物件有多大,需要多少記憶體。因此就誕生了鏈式儲存的順序表,即鍊錶;鍊錶也是分為三種,傳統鍊錶、核心鍊錶,和企業鍊錶。那麼這三種鍊錶分別有什麼特點呢?
(1)傳統鍊錶:傳統鍊錶區別於陣列模擬的線性表,可以不用管到底需要多大的記憶體,比較方便。第二個特點是他的記憶體不是連續的,每個結點包含乙個資料域和指標域。每個節點的指標域儲存的是下乙個節點的位址。他的缺點在於,如果節點的成員變數發生改變(新增或者刪除)那麼整個程式都要隨之改變。
(2)核心鍊錶:核心鍊錶全名為linux核心鍊錶,由linux之父linus(托瓦爾茲)發明。發明這個鍊錶的原因是基於以上的問題,傳統鍊錶不能包含世間萬物,那索性他就不包含了,反過來讓世間萬物包含我,是不是很有哲學思想。他的缺點在於,指標節點在結構體內有乙個位址偏移量。
(3)企業鍊錶:基於上面的問題,核心鍊錶的指標成員變數有乙個偏移量,那麼企業鍊錶的改變在於,將指標成員變數前移至第乙個成員變數,這樣整個結構體的記憶體位址和第乙個成員變數(即指標成員變數)就重合了,解決了位址偏移量的 問題;他們的技術推演路線圖如下:
我們平時用的就是傳統鍊錶和企業鍊錶。下面我們來看這兩種鍊錶用c/c++的實現方式:
//傳統鍊錶
// 資料結構.cpp : 此檔案包含 "main" 函式。程式執行將在此處開始並結束。
//#include
using
namespace std;
typedef
struct node
slist;
slist*
creatlist()
;int
printslist
(slist* phead)
;int
delnode
(slist*
,int x)
;int
insertnode
(slist*
,int x,
int y)
;int
destroynode
(slist*);
intmain()
slist*
creatlist()
else
cout <<
"please inter your data"
<< endl;
cin >> x;
pcur = phead;
while
(x!=-1
)else
}return phead;
}int
printslist
(slist* phead)
tmp = phead-
>next;
while
(tmp)
return0;
}//單項鍊表的位置儲存在前驅節點的next中
intinsertnode
(slist* phead,
int x,
int y)
ppre = pcur;
pcur = pcur-
>next;
}return0;
}int
delnode
(slist* phead,
int x)
ppre = pcur;
pcur = pcur-
>next;}if
(pcur ==
null
) ppre-
>next = pcur-
>next;
free
(pcur)
;return0;
}int
destroynode
(slist* phead)
return0;
}//上面部分是傳統鍊錶的一些基本操作;下面我們來看企業鍊錶的一些api函式;
//企業鍊錶,企業鍊錶我們將業務結點和演算法分開實現;
//定義乙個企業鍊錶的標頭檔案,將結點的定義和api函式的實現全部包含進來
//link_list.h
#ifndef _mylinklist_h_
#define _mylinklist_h_
typedef
void linklist;
typedef
struct _tag_linklistnode
linklistnode;
//定義乙個結點,後面講這個結點包含進去業務節點,然後將這個結點連起來,所有的業務結點就自然而然的連起來了;
linklist*
linklist_creat()
;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)
;#endif
//鍊錶及其基本api函式的底層實現
//link_list.cpp
#include
#include
"linklist.h"
using
namespace std;
typedef
struct _tag_linklist
tlinklist;
linklist*
linklist_creat()
memset
(tmp,0,
sizeof
(tlinklist));
return tmp;
}void
linklist_destroy
(linklist* list)
free
(list)
;return;}
void
linklist_clear
(linklist* list)
tlist-
>header.next =
null
; tlist-
>length =0;
return;}
intlinklist_length
(linklist* list)
return tlist-
>length;
}int
linklist_insert
(linklist* list, linklistnode* node,
int pos)
for(i =
0; i < pos; i++
) node-
>next = pcur-
>next;
pcur-
>next = node;
tlist-
>length++
;return0;
}linklistnode*
linklist_get
(linklist* list,
int pos)
for(i =
0; i < pos; i++
)return pcur-
>next;
}linklistnode*
linklist_delete
(linklist* list,
int pos)
for(i =
0; i < pos; i++
) ret=pcur-
>next;
pcur-
>next = ret-
>next;
tlist-
>length--
;//free(ret);
return ret;
}//上層測試函式
//鍊錶框架搭建及實現.cpp
#include
#include
"linklist.h"
using
namespace std;
//思考1:業務節點和鍊錶演算法是如何分離的
//思考2:業務節點的生命週期歸測試程式管;
typedef
struct _teacher//業務節點
teacher;
void
main()
//刪除鍊錶;
while
(linklist_length
(list)
>0)
linklist_destroy
(list)
;return
;}
鍊錶的C語言實現
編輯 c巨集例項 以下 摘自linux核心2.6.21.5原始碼 部分 展示了鍊錶的另一種實現思路,未採用ansi c標準,採用gnu c標準,遵從gpl版權許可。struct list head define list head init name define list head name st...
雙向鍊錶C語言實現
ifndef stdlist h define stdlist h typedef struct tagstdnode stdnode,lpstdnode typedef struct tagstdlist stdlist,lpstdlist 鍊錶資料結構 struct tagstdnode 鍊錶節...
線性鍊錶 C語言實現
include include define error 0 define ok 1 define equal 1 define overflow 1 define list init size 100 define listincrement 10 struct stustu 50 typedef...