資料結構學習 線性表

2021-10-21 10:03:49 字數 4975 閱讀 5387

線性表,全名為線性儲存結構。使用線性表儲存資料的方式可以這樣理解,即「把所有資料用一根線兒串起來,再儲存到物理空間中」。

所謂「一對一」的關係是指,乙個元素只有乙個前驅和乙個後繼,而且元素的內容是相同的,比如去圖書館佔位置就是在一片連續的空間佔一定大小的位置,可以不從開始佔,選乙個風水好的地方,但如果用書包和筆等東西來佔位置就是不行的,因為元素不一樣。

線性表的儲存方式分為線性和非線性,如上文所說,線性儲存方式就是在記憶體空間中開闢一段連續的空間,物理上相鄰,邏輯上也相鄰,可以用陣列來實現,稱之為順序儲存鍊錶。

具體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;

}

獲取元素操作

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)

;}

為了解決順序儲存方式插入的不方便(時間複雜度為o(n)),研究者們想到了利用指標來實現物理位置不同,但邏輯相鄰的鍊錶,就像偵探解密一樣,到了乙個地兒,會有線索指示你到下乙個元素的地兒,當沒有元素,也就是null了。

鍊錶的實現:

結點的定義

typedef

struct slistnode

slistnode;

鍊錶的初始化

值得注意的是,鍊錶可以沒有頭結點,但必須要有頭指標,具體差別就在於對於第乙個結點的表示,比如帶頭結點的鍊錶list,它的第乙個結點是list->next;而不帶頭結點的鍊錶 list,它的第乙個結點表示為 *list。

//鍊錶初始化   帶頭結點  

slistnode*

initlist()

在第 i 個元素之前插入結點

插入元素,首先要判斷插入點是否合理,然後建立乙個結點 s,將要插入的數值放在裡面,遍歷鍊錶找到第i-1個結點 p ,然後將 p 的後繼賦給 s 的後繼,p的後繼改為 s。

// 插入第 i 個結點之前

intinsertlistx

(slistnode* pheader,

int i,

int val)

else

node->next = cur->next;

cur->next = node;

return1;

}}

刪除第 i 個元素,並返回其值

刪除第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 單鏈表只能順序查詢插入...