表,棧和佇列

2021-08-08 02:48:07 字數 3898 閱讀 1290

對錶的所有操作都可以使用陣列來實現。雖然陣列是靜態分配的,但是內部儲存陣列的ve

ctor

類允許在需要時的時候將陣列的大小增加一倍。這解決了使用陣列是需要對錶的大小的最大值進行估計的問題。

陣列實現使得pr

intl

ist 以線性時間執行,而fi

ndkt

h 則花費常數時間。然而,插入和刪除的花費有可能是昂貴的,這取決與插入和刪除發生的位置。在最壞的情況下,在位置

0 (在表的最前面)插入需要將整個陣列後移乙個位置以空出空間來;則刪除第乙個元素則需要將表中的所有元素前一乙個位置,因此這兩種操作的最壞情況為o(

n)。平均來看,這兩種運算操作都需要移動表的一半的元素,因此仍需要線性時間。另一方面,如果所有的操作都發生在表的末尾,就不需要移動任何元素,那麼新增和刪除的操作都將花費o(

1)時間。

為了避免插入和刪除的線性開銷,需要允許表的不連續儲存,否則表的部分或全部就需要整體移動。鍊錶由一系列不必存在記憶體中的相連的節點組成。每乙個結點均含有表元素和到包含該元素後繼元的結點的鏈(l

ink)

。我們稱之為ne

xt鏈。最後乙個單元的ne

xt鏈指向nu

ll。為了執行pr

intl

ist(

) 或fi

nd(x

) ,我們只需要從表的第乙個結點開始然後用ne

xt鏈遍歷該錶即可。與陣列實現一樣,這種操作顯然是花費線性時間的,但是這個常數可能比用陣列實現時要大。fi

ndkt

h 操作不如陣列實現時的效率高;fi

ndkt

h(i)

花費o(

i)的時間並以明顯的方式遍歷鍊錶完成。在實踐中這個界是保守的,因為呼叫fi

ndkt

h 常常是以(按

i )排序的方式進行。

頭插法:在頭結點(為了操作方便,在單鏈表的第乙個結點之前附加乙個結點,稱為頭結點。頭結點的資料域可以儲存資料標題、表長等資訊,也可以不儲存任何資訊,其指標域儲存第乙個結點的首位址)。head之後插入資料,其特點是讀入的資料順序與線性表的邏輯順序正相反。

p->next=head->next;

head->next=p;

尾插法:將每次插入的新結點放在鍊錶的尾部

s->next=r->next;

r->next=s;

r=s;

1.給定兩個鍊錶,分別表示兩個非負整數。它們的數字逆序儲存在鍊錶中,且每個結點只儲存乙個數字,計算兩個數的和,並且返回和的煉表頭指標。

如:輸入:2—

4—3,

5—6—

4 ,輸出7—

0—8 。

typedef  struct tagsnode

}snode;

snode* add(snode* phead1,snode* phead2)

//處理較長的鏈

snode* p=p1?p1:p2;

while(p)

//處理可能存在的進製

if(carry!=0)

ptail->pnext=new snode(carry);

return psum;

}

2.鍊錶的部分原地翻**給定乙個鍊錶,翻轉該鍊錶從

m 到

n的位置。要求直接翻轉而非直接申請空間。假定給出的引數滿足

1<=

n<=

m<=

鍊錶的長度。

typedef  struct tagsnode

}snode;

void reverse(snode* phead,int

from,int to)

snode* ppre=pcur;

pcur=pcur->pnext;

to--;

snode* pnext;

for(;i//以head為起始結點遍歷n-m次,將第i次時,將找到的結點插入到head的next中即可

pnext = pcur->pnext;

pcur->pnext = phead->pnext;

phead->pnext = pcur; //頭插法

ppre->pnext = pnext;

pcur = pnext;

}}

3.(1)給定排序的鍊錶,刪除重複元素,只保留重複元素第一次出現的結點:若p−

>ne

xt的值和

p 的值相等,則將p−

>ne

xt−>ne

xt賦值給p

,刪除p−

>ne

xt;重複上述過程,直至鍊錶尾端。

(2)若發現重複元素則重複元素全部刪除。

typedef  struct tagsnode 

}snode;

void deleteduplicatenode(snode* phead)

else

}}void deleteduplicatesnode2(snode* phead )

ppre=pcur;

pcur=pnext;

}}void deleteduplicatesnode3(snode* phead )

if (bdup) //此刻的pcur與原資料重複,刪之

else

pcur = pnext;

}}

4.給定乙個鍊錶和乙個值

x ,將鍊錶劃分為兩部分,是得劃分後小於

x的結點在前,大於

x 的結點在後。這兩部分要保持原煉表中的出現順序。

分別申請兩個指標p1

和p2 ,小於

x 的新增到p1

中,大於等於

x 的新增到p2

中;最後,將p2

鏈結到p1

的末端即可,時間複雜度是o(

n),空間複雜度為o(

1);該問題可以說明:快速排序對於單鏈表儲存結構仍然適用,但不是所有排序都方便使用鍊錶儲存。

void partition(snode* phead, int pivotkey)

else

p=p->pnext;

}//將right鏈結到left尾部

left->pnext=prighthead->pnext;

right->pnext=

null;

//將整理好的鍊錶賦值給當前鍊錶頭部

phead->pnext=plefthead->pnext;

delete plefthead;

delete prighthead;

}

5.單鏈公共結點問題,令兩鍊錶的長度為

m 、

n,不妨設

m>=

n ,由於兩個鍊錶從第乙個公共結點到鍊錶的尾結點是完全重合的。所以前面的(m

−n) 個結點一定沒有公共結點。演算法:先分別遍歷兩個鍊錶得到它們的長度

m ,

n。同步遍歷兩鍊錶,直到周到相同結點或到鍊錶結束,時間複雜度為o(

m+n)

typedef

struct tagsnode

}snode;

int calclength(snode* p)

return nlen;

}snode* findfirstsamenode(snode* pa,snode* pb)

for(int i=0;iif(pa==pb)

return pa;

pa=pa->pnext;

pb=pb->pnext;

}return

null;

}

表 棧和佇列

形如 a1,a2,a3 an 的表,這個表的大小為 n,而大小為 0的表稱為空表,非空表中,ai 1 後繼ai ai 1 前驅ai 表adt 的相關操有 printlist 列印表中的元素 createempty 建立乙個空表 find 返回關鍵字首次出現的位置 insert 和delete 從表的...

表 棧和佇列

表 棧和佇列是最簡單和最基本的三種資料結構 資料結構與演算法分析 c 語言描述 應用範疇 i.多項式 adt i.基數排序 多趟桶式排序 實現 i.多重表 鍊錶的游標實現 實現 棧又叫做 lifo 後進先出 表 資料結構與演算法分析 c 語言描述 應用範疇 i.平衡符號 i.字尾表示式 有中綴表示式...

鍊錶,棧和佇列

1.建立鍊錶 package com.zzw.鍊錶 非常基本的單項鍊表 author john public class node 新增乙個結點 node end new node d node n this while n.next null n.next end 刪除單向鍊錶中的結點 node ...