資料結構 線性表 棧和佇列

2021-09-27 06:32:56 字數 4070 閱讀 9505

資料概念

資料是對客觀事物的符號表示

資料元素是資料的基本單位

資料物件是性質相同的資料元素的集合

資料結構是相互間存在一種或多種特定關係的資料元素集合,是元素的有限集+元素上關係的有限集

資料的關係包括邏輯結構和儲存結構

資料型別是乙個值的集合和定義在這個值集上的一組操作的總稱

抽象資料型別adt 是乙個數學模型以及定義在該模型上的一組操作的總稱

演算法演算法必須具有有窮性、確定性、可行性、輸入輸出

演算法的時間複雜度:選取演算法中是基本操作的原操作,以其重複執行的次數來評估。由於經常無法精確計算次數,則可以求出它關於n的增長率或階數即可。有的情況下,因資料集不同,時間複雜度也不同,此時可以用它最壞情況下的時間複雜度作為乙個上界

空間複雜度,對儲存空間需求的程度

由結點集n以及定義在結點集n上的線性關係r

(1)有乙個唯一的開始節點,無前驅,有唯一後繼

(2)對於有限集n 存在乙個唯一的終止結點,無後繼,有唯一前驅

(3)其他為內部結點,有唯一前驅和唯一後繼

(4)線性表的節點個數稱為長度,長度為0線性表稱為空表

(5) 線性關係r簡稱前驅關係,應具有反對稱和傳遞性

取值空間+運算集

template 

class list

定長的一維陣列結構 (向量型儲存結構)

變長的線性儲存結構 鏈結型儲存結構。用前驅和後繼關係將各個元素用指標連線起來

總之用一組連續的資料單元儲存資料元素,以物理位置的相鄰來表示資料元素的邏輯關係

(1) 建立例項

(2) 消除例項並釋放空間

(3) 獲取資訊比如讀取元素內容,由內容尋找位置

(4)訪問線性表並改變內容或者結構

(5) 輔助操作 比如統計長度

元素型別相同;元素順序儲存,對於順序儲存的線性表,插入與刪除時,對應的其他元素要依次後移或前移,成為了線性表的缺點,故改用鍊錶克服

每個元素占用l個儲存單元,順序表開始結點k

0k_0

k0​的儲存位置記為b=l

oc(k

0)

b=loc(k_0)

b=loc(

k0​)

稱為順序表的首位址或者基位址,故下標為i的元素位址為 loc

(ki)

=b+i

×l

loc(k_i)=b+i\times l

loc(ki

​)=b

+i×l

順序表是一種隨機訪問的結構,兩個物理位置相鄰的元素互為前驅和後繼,故物理相鄰反映了邏輯相鄰

插入元素

刪除元素

用一組任意的儲存單元儲存線性表的資料元素,其中儲存資料元素的域稱為資料域,儲存直接後繼位置的域稱為指標域。n個這樣的結點連線成乙個鍊錶。整個鍊錶的訪問必須從頭指標開始

如果每個結點只包含指向後繼的指標,則稱為單鏈表,頭指標指示鍊錶中第乙個結點,整個鍊錶的訪問必須從頭指標開始,因此單鏈表是非隨機訪問的結構

指標是資料元素之間的邏輯關係的映像,任何兩個元素的儲存位置沒有固定的聯絡,因此兩個邏輯上相鄰的結點儲存位置不一定相鄰

template 

class listnode

listnode

(const linknode

* nextptr)

:next

(nextptr)

}

插入資料元素,首先生成乙個結點,再將前驅結點指標域賦給該結點指標域,再將該結點位址賦給前驅結點指標域

void

insert

(linkedlist &l,

int i,

int e)

刪除乙個結點,僅需修改直接前驅的指標即可

void

delete

(linkedlist &l,

int i)

插入和刪除演算法的時間複雜度都為o(n)因為在第n個結點前插入或者刪除結點,必須首先尋找到該結點的前驅

為克服鍊錶的單向性,增加乙個指標域指向其前驅結點,但增加了插入元素和刪除元素的難度,需修改兩個方向上的指標,如在p前插入s結點s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s;刪除時:p->prior->next=p->next; p->next->prior=p->prior;鍊錶合併時,兩個指標指向比較插入的結點,另乙個指標指向鍊錶中最後乙個結點並將較小結點接在其後面

單向鍊錶想找某結點的前驅需要從頭結點開始遍歷鍊錶,故採用雙向鍊錶簡化操作。雙向鍊錶中有兩個指標域,乙個指示直接前驅,乙個指示直接後繼

插入

void

listinsert

(duallink &d,

int i,

int val)

void

listdelete

(duallink &d,

int i)

迴圈鍊錶的最後乙個結點的指標域指向頭結點,操作與線性鍊錶基本一致,但是判斷是否尾結點的條件為tail->next==head而非tail->next==nullptr;迴圈鍊錶合併時,找尾結點,a->next=b->next->next; b->next=a』->next

如果經常插入刪除 不要使用線性表,線性表最大長度是重要因素

當隨機訪問操作比插入刪除頻率高,不使用鍊錶; 如果指標儲存開銷比例較大,要慎重選擇

一般來說 鍊錶是線性表的首選儲存結構,但是它不能隨機訪問,求長度時也不如線性表簡單,且邏輯關係不能表示物理位置關係。

限制訪問的線性表,lifo,有插入和彈出操作,表首被稱為棧頂,棧的另一端為棧底,且棧頂指標始終在棧頂元素的下乙個位置上,分為順序棧和鏈式棧(指標方向從棧頂向下鏈結)

棧的應用:數制轉換、push(s,n%8); n=n/8 再依次出棧可轉換為八進位制。檢驗括號匹配、迷宮求解,表示式求值

void stack:

:push

(float item)

float stak:

:pop()

實際應用中順序棧應用廣泛,因為比較容易根據棧頂位置快速定位並讀取棧的內部元素,讀取元素所需時間為o(1) 而鏈式棧需要遍歷

一般棧不允許訪問內部元素,只能棧頂操作

遞迴實現表示式求值

符號集合:0~9 和運算符號

中綴表示式需要括號改變優先順序

棧與遞迴

hanoi塔核心函式

void

hanoi

(int n,

char x,

char y,

char z)

}

先進先出表,

template 

class queue

鏈式佇列不需要判斷佇列是否滿,常用的儲存結構有順序佇列和鏈式佇列

兩個變數指向隊頭和隊尾,但是如果按順序表的實現方法,如果從陣列後面入隊,出佇列時間代價o(n)因為需要把前面的元素向前移動乙個位置,入佇列時間代價o(1)

如果不進行元素的移動,會出現假上溢位,就是front和rear都指向隊尾,儘管此時隊列為空,但也無法插入元素,所以引入迴圈佇列

線性佇列在不斷入隊出隊後,會有空間剩餘,所以構造為環形佇列,某乙個元素的直接後繼是(x+

1)%m

size

(x+1)\%msize

(x+1)%

msiz

e,但是rear=front時無法判斷佇列滿還是佇列空,所以往往空出乙個位置,以(re

ar+1

)%ms

ize=

=fro

nt

(rear+1)\%msize==front

(rear+

1)%m

size

==fr

ont作為佇列滿的標誌

資料結構 線性結構(線性表 棧與佇列)

線性表的抽象定義集合a和集合b的並集操作線性表的順序儲存的結構 位址計算獲得元素操作 getelem插入操作 listinsert刪除操作 lisedelete優缺點比較。線性表的單鏈表儲存結構 linklistgetelemlistinsertlistdeletecreatelisthead 頭插...

資料結構 線性表 (棧,佇列,串)

定義 n個元素的有限序列 記為 a1,a2,a3,an 特點 存在唯一表頭表尾。除了表頭,每個元素只有乙個直接前驅。除了表尾,每個元素只有乙個直接後驅。儲存結構 1 順序儲存 位址連續的儲存單元,依次儲存表中資料元素。使得邏輯相鄰的元素,物理位置上也相鄰 優點 隨機訪問表中元素。loc元素位置 l元...

資料結構 線性表 佇列

一 佇列簡介 佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端 front 進行刪除操作,而在表的後端 rear 進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。佇列中沒有元素時,稱為空佇列。include include typede...