線性表,全名為線性儲存結構。使用線性表儲存資料的方式可以這樣理解,即「把所有資料用一根線兒串起來,再儲存到物理空間中」。
所謂「一對一」的關係是指,乙個元素只有乙個前驅和乙個後繼,而且元素的內容是相同的,比如去圖書館佔位置就是在一片連續的空間佔一定大小的位置,可以不從開始佔,選乙個風水好的地方,但如果用書包和筆等東西來佔位置就是不行的,因為元素不一樣。
線性表的儲存方式分為線性和非線性,如上文所說,線性儲存方式就是在記憶體空間中開闢一段連續的空間,物理上相鄰,邏輯上也相鄰,可以用陣列來實現,稱之為順序儲存鍊錶。
具體c實現可如下**所示:
首先是定義資料結構:
然後是初始化,建立線性表。typedef
int elemtype;
typedef
struct
sqlist;
//建立線性表
intinitlist
(sqlist &l)
l.length =0;
l.listsize = list_init_size;
return0;
}
值得注意的是,線性表的下標是從「1」開始的,而儲存位置的下標是從「0」開始的。即線性表第i個元素儲存在第i-1個下標位置。loc(a_(i+1)) = loc(a_i) + c
loc(a_i) = loc(a_1) + (i-1)*c
其中 c 是指資料元素所佔儲存單元,比如 int 是 32位 4個位元組
獲取元素操作// 插入元素
intlistinsert
(sqlist &l,
int i,elemtype e)
//插入操作
elemtype *q,
*p;//定義兩個指標變數
q =&(l.elem[i-1]
);//q為插入位置,i是從1開始的
for(p=
&(l.elem[l.length-1]
);p >= q;
--p)
//從ai到an-1依次後移,注意後移操作要從後往前進行
*q = e;
//插入位置賦值
++l.length;
//表長加1
return0;
}
為了解決順序儲存方式插入的不方便(時間複雜度為o(n)),研究者們想到了利用指標來實現物理位置不同,但邏輯相鄰的鍊錶,就像偵探解密一樣,到了乙個地兒,會有線索指示你到下乙個元素的地兒,當沒有元素,也就是null了。int
main
(int argc,
char
**ar**)
printf
("list.length:%d\nlist.listsize:%d\n"
,list.length,list.listsize)
;listinsert
(list,3,
7);for
(int i=
0;i<
10;i++
)printf
("\n");
printf
("list.length:%d\nlist.listsize:%d\n"
,list.length,list.listsize)
;}
鍊錶的實現:
結點的定義
鍊錶的初始化typedef
struct slistnode
slistnode;
值得注意的是,鍊錶可以沒有頭結點,但必須要有頭指標,具體差別就在於對於第乙個結點的表示,比如帶頭結點的鍊錶list,它的第乙個結點是list->next;而不帶頭結點的鍊錶 list,它的第乙個結點表示為 *list。
在第 i 個元素之前插入結點//鍊錶初始化 帶頭結點
slistnode*
initlist()
插入元素,首先要判斷插入點是否合理,然後建立乙個結點 s,將要插入的數值放在裡面,遍歷鍊錶找到第i-1個結點 p ,然後將 p 的後繼賦給 s 的後繼,p的後繼改為 s。
刪除第 i 個元素,並返回其值// 插入第 i 個結點之前
intinsertlistx
(slistnode* pheader,
int i,
int val)
else
node->next = cur->next;
cur->next = node;
return1;
}}
刪除第i個元素,首先遍歷找到第 i - 1個結點 p,和第 i 個結點 q,然後將p的後繼改為q的後繼,即p的下下個結點,跳過了q,然後將q的記憶體釋放點即可。
完整**如下:// 刪除鍊錶的第 i 個元素,並返回其值
intslistdeletex
(slistnode* pheader,
int i,
int&e)if(
!(p->next)
|| j>i)
return0;
q = p->next;
//第i個結點
p->next = q->next;
// 將q的後繼賦給p的後繼
e = q->data;
free
(q);
return1;
}
#include
#include
#include
#include
using
namespace std;
//定義單鏈表
typedef
struct slistnode
slistnode;
slistnode*
initlist()
;int
printlinklist
(slistnode* pheader)
;int
slistpushback
(slistnode* pheader,
int val)
;int
slistpushhead
(slistnode* pheader,
int val)
;int
slistdeletex
(slistnode* pheader,
int i,
int&e)
;int
lengthoflist
(slistnode* pheader)
;int
insertlistx
(slistnode* pheader,
int i,
int val)
;int
slistdeleteend
(slistnode* pheader,
int&e)
;int
main
(int argc,
char
** ar**)
//鍊錶初始化 帶頭結點
slistnode*
initlist()
//列印鍊錶
intprintlinklist
(slistnode* pheader)
if(pheader-
>next ==
null
) slistnode* cur = pheader-
>next;
//頭結點
int num =1;
while
(cur !=
null
)return0;
}// 鏈尾插入結點
intslistpushback
(slistnode* pheader,
int val)
else
cur-
>next = node;
}return1;
}//鏈頭插入結點
intslistpushhead
(slistnode* pheader,
int val)
else
//煉表裡有元素
return1;
}// 刪除鍊錶的第 i 個元素,並返回其值
intslistdeletex
(slistnode* pheader,
int i,
int&e)if(
!(p-
>next)
|| j>i)
return0;
q = p-
>next;
//第i個結點
p->next = q-
>next;
// 將q的後繼賦給p的後繼
e = q-
>data;
free
(q);
return1;}
// 刪除煉錶鏈尾的結點
intslistdeleteend
(slistnode* pheader,
int&e)
// 求鍊錶長度
intlengthoflist
(slistnode* pheader)
else
return len;}}
// 插入第 i 個結點之前
intinsertlistx
(slistnode* pheader,
int i,
int val)
else
node-
>next = cur-
>next;
cur-
>next = node;
return1;
}}
資料結構學習 線性表
線性表一般分為順序結構和鏈式結構。順序表裡面元素的位址是連續的,如陣列 鍊錶裡面節點的位址不是連續的,是通過指標連起來的,如單鏈表 順序結構 優點 易於查詢,索引快 list n 這樣的操作,o 1 複雜度。缺點 擴充套件性弱,不易刪除 插入,這兩項操作均是o n 的時間複雜度 鍊錶結構 優點 擴充...
資料結構學習 線性表
考試前複習下資料結構,把一些知識點整理在這!主要參考了殷人昆主編的 資料結構 用物件導向方法與c 語言描述 這本書,以及中山大學劉聰老師的課件內容!鍊錶雙鏈表 線性表 linear list 是由n n 0 個資料元素 結點 a 0 a 1 a 2 a n 1 組成的有限序列。維基百科 線性表是乙個...
資料結構學習 線性表
鏈式儲存用指標表示邏輯結構,可以很方便的表示各種邏輯結構。順序儲存結構中,插入和刪除結點需要大量的移動元素,效率很低。順序儲存結構既可以順序訪問也可以隨機訪問,而鏈式結構只可以順序訪問。對n個元素進行排序的時間複雜最快也要o n 初始有序 通常是o nlog2n 或o n 2 單鏈表只能順序查詢插入...