對錶的所有操作都可以使用陣列來實現。雖然陣列是靜態分配的,但是內部儲存陣列的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;
1.給定兩個鍊錶,分別表示兩個非負整數。它們的數字逆序儲存在鍊錶中,且每個結點只儲存乙個數字,計算兩個數的和,並且返回和的煉表頭指標。s->next=r->next;
r->next=s;
r=s;
如:輸入:2—
4—3,
5—6—
4 ,輸出7—
0—8 。
2.鍊錶的部分原地翻**給定乙個鍊錶,翻轉該鍊錶從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;
}
m 到
n的位置。要求直接翻轉而非直接申請空間。假定給出的引數滿足
1<=
n<=
m<=
鍊錶的長度。
3.(1)給定排序的鍊錶,刪除重複元素,只保留重複元素第一次出現的結點:若p−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;
}}
>ne
xt的值和
p 的值相等,則將p−
>ne
xt−>ne
xt賦值給p
,刪除p−
>ne
xt;重複上述過程,直至鍊錶尾端。
(2)若發現重複元素則重複元素全部刪除。
4.給定乙個鍊錶和乙個值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;
}}
x ,將鍊錶劃分為兩部分,是得劃分後小於
x的結點在前,大於
x 的結點在後。這兩部分要保持原煉表中的出現順序。
分別申請兩個指標p1
和p2 ,小於
x 的新增到p1
中,大於等於
x 的新增到p2
中;最後,將p2
鏈結到p1
的末端即可,時間複雜度是o(
n),空間複雜度為o(
1);該問題可以說明:快速排序對於單鏈表儲存結構仍然適用,但不是所有排序都方便使用鍊錶儲存。
5.單鏈公共結點問題,令兩鍊錶的長度為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;
}
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 ...