1. 以Niklus Wirth的觀點,程序等於什么? =數據結構+算法
2. 算法的重要特性:確定、有窮、能行、輸入、輸出
3. 好算法的標准:正確、可讀、健壯、高效低存貯
4. 數據結構主要研究對象:邏輯結構、存貯結構和運算(增刪改查)
5. 數據的邏輯結構有幾大類?(線性、非線性)
6. 數據的存貯結構有幾類?(順序、鏈式、索引、散列hash)
7. 對數據的最主要的操作:增刪改查
8. 線性結構的特點:
在數據元素的非空有限集中
存在唯一一個被稱做"第一個"的數據元素;
存在唯一一個被稱做“最后一個”的數據元素;
除第一個元素外,每個數據元素均有唯一一個直接前驅;
除最后一個元素外每個數據元素均有唯一一個直接后繼。
9. 線性結構與非線性結構的區別。
在線性結構中,該數據結構中的元素是一對一的關系,非線性結構就不是了
線性結構是最簡單最常用的一種數據結構,線性結構的特點是結構中的元素之間滿足線性關系,按這個關系可以把所有元素排成一個線性序列.線性表,串,棧和隊列都屬於線性結構.
非線性結構是指在該類結構中至少存在一個數據元素,它具有兩個或者兩個以上的前驅或后繼.如樹和二叉樹等.
10. 列出所學過的線性結構與非線性結構。
線性結構:線性表、隊列、棧、數組、串
非線性結構:廣義表、樹、圖
11. 頭指針、頭結點、首元結點的區別。
頭指針是指向鏈表中第一個結點(或為頭結點或為首元結點)的指針;
頭結點是在鏈表的首元結點之前附設的一個結點;數據域內只放空表標志和表長等信息(內放頭指針?那還得另配一個頭指針!)
首元素結點是指鏈表中存儲線性表中第一個數據元素a1的結點.
12. 帶頭結點和不帶頭結點的線性鏈表的區別。
帶頭結點的單鏈表和不帶頭結點的單鏈表的區別主要體現在其結構上和算法操作上。
在結構上,帶頭結點的單鏈表,不管鏈表是否為空,均含有一個頭結點,不帶頭結點的單鏈表不含頭結點。
在操作上,帶頭結點的單鏈表的初始化為申請一個頭結點。無論插入或刪除的位置是地第一個結點還是其他結點,算法步驟都相同。不帶頭結點的單鏈表,其算法步驟要分別考慮插入或刪除的位置是第一個結點還是其他結點。因為兩種情況的算法步驟不同
13. 單鏈表、雙鏈表、循環鏈表的區別、各自的優缺點及怎樣決定選取何種存貯結構。
單鏈表:每個結點中只包含一個指針域
優點:插入和刪除時候不需要移動大量的元素
缺點:指針只能單方向移動
雙鏈表:有兩個指針域,其一指向直接后繼,其二指向直接前驅
優點:查找直接前驅的時候,則從頭指針出發,能夠克服單鏈表這種單向性的缺點
缺點:插入刪除操作時需要修改多個指針域
循環鏈表:最后一個結點的指針域指向頭結點
優點:使兩個表連接起來就很簡單,這個操作僅需兩個指針即可,插入、刪除時,不會斷鏈等。
缺點:不容易確定退出循環的條件
14. 棧和隊列是什么樣的線性表?
棧與隊列是操作受限制的線性表
15. 指出順序線性表、順序棧、順序隊列的區別。
相同:他們都是線性表,都是一維數組,
不相同:操作不同而已;
線性表:任意位置操作
棧:棧頂操作
隊列:尾進頭出
16. 例舉棧和隊列的實例及用棧和隊列所能解決的問題。
棧:鐵路中轉站,餐廳的食物盤, 子彈殼。
隊列:操作系統作業排隊,排隊買東西
棧解決的問題是:后進先出的數據(LIFO)
隊列解決的問題:先進先出的數據 (FIFO)
17. 指出通常解決隊列和棧溢出時所能用到的方法。
隊列:雙向隊列,鏈隊列,循環隊列
棧:雙棧共享,多棧共享,鏈棧
18. 循環隊列的循環是怎樣實現的?
隊頭、隊尾指針加1,用取模(余數)運算實現循環
19. 給出對稱矩陣、三角矩陣、對角矩陣節省內存的存貯結構並寫出相應的輸入、輸出算法。
對稱矩陣的存貯結構:
利用 = 來存儲(以按行存儲為例)
K=I(I-1)/2 +J-1 I>=J;
K=J(J-1)/2 +I-1 I<J;
k 是對稱矩陣位於(i,j)位置的元素在一維數組中的存放位置,從0開始
| a11 |
a21 |
a22 |
a31 |
…… |
ann |
三角矩陣的存貯結構:
以下三角為例,當i<j時,aij=0
K=0的位置存儲0
| 0 |
a11 |
a21 |
a22 |
…… |
a |
對角矩陣的存貯結構:
記住loc( aij )=loc( a11 )+( 2i+j-3 ) L i-1<=j<=i+1
輸入輸出算法:自己寫(你應該會寫了)
20. 給出稀疏矩陣的節省內存的存貯結構並寫出相應的輸入、輸出算法。
為了節省存儲單元,可只存儲非零元素。由於非零元素的分布一般是沒有規律的,因此在存儲非零元素的同時,還必須存儲非零元素所在的行號、列號,才能迅速確定一個非零元素是矩陣中的哪一個元素。其中每一個非零元素所在的行號、列號和值組成一個三元組,並由此三元組惟一確定。
三元組表
#define MAXSIZE 100 //非零元個數的最大值
typedef struct{
int i,j; // 行下標,列下標
ElemType e; // 非零元素值
}Triple;
typedef struct
{Triple data[MAXSIZE+1]; //非零元三元組表,data[0]未用
int mu,nu, tu; // 矩陣的行數、列數和非零元個數
}TSMatrix;
十字鏈表
typedef struct OLNode //結點的定義
{int i,j; // 非零元的行和列下標
ElemType e; // 非零元素值
struct OLNode *right,*down; // 該非零元所在行表和列表的后繼鏈域
}OLNode, *OLink;
typedef struct //鏈表的定義
{ OLink *rhead,*chead; // 行和列鏈表頭指針向量基址,由CreatSMatrix_OL()分配
int mu,nu,tu; // 稀疏矩陣的行、列數和非零元個數
}CrossList;
輸入輸出算法(你應該自己會寫啦)
21. 用十字鏈表存貯稀疏矩陣時, 矩陣的每個元素同時在幾條鏈上, 分別被稱為什么鏈?
兩條鏈:行鏈和列鏈
22. 給出樹的不同的幾種表示(圖示)形式。
(一)層次表示法 (二)廣義表表示法
(三)嵌套表示法 (四)凹入法表示法


23. 在二叉樹的第 i層上至多有多少個結點。深度為 K的二叉樹至多有多少個結點。

24. 在一顆二叉樹中, 其葉子結點數n0和度為二的結點數n2之間的關系。

25. 有 n個結點的完全二叉樹的深度。

26. 在二叉樹的順序存貯結構中如何求結點的雙親、孩子?
雙親:i/2; 左孩子:2*i; 右孩子:2*i+1;
27. 有 n個結點的二叉樹用二叉鏈表存貯時有多少個空鏈域,用三叉鏈表存貯時有多少個空鏈域。
二叉:n+1個空鏈域
三叉:n+2個空鏈域
28. 為什么可在不增加指針域的情況下,對二叉樹進行線索化,線索化的目的是什么?
a.利用n+1個空鏈域
b.目的:遍歷方便
29. 對於已線索化二叉樹如何識別指針域是指向孩子還是其后繼結點?
增加標志域 LeftThread和RightThread
LeftThread=0, LeftChild為左孩子指針
LeftThread=1, LeftChild為前驅線索
RightThread=0, RightChild為右孩子指針
RightThread=1, RightChild為后繼指針
30. 樹的幾種存貯結構(雙親表示法、孩子表示法、孩子兄弟表示法)的優缺點,各自適應的運算。
雙親表示法:便於查找雙親,
缺點:找孩子難
孩子表示法:便於涉及到孩子的操作,
缺點:找雙親難
孩子兄弟法:操作容易
缺點:破壞了樹的層次
31. 哪種存貯結構可將森林轉為二叉樹。對此種結構的各個域給予注釋。說明在這個結構中怎樣找到森林的n棵樹。
孩子兄弟表示法,左指針是第一個孩子,右指針是第一個兄弟,最右的為第n棵樹
32. 樹的先根遍歷、后根遍歷對應其二叉樹的哪種遍歷,森林的先根遍歷、中根遍歷對應其二叉樹的哪種遍歷?
樹的先根遍歷對應二叉樹的先序遍歷;
樹的后根遍歷對應二叉樹的中序遍歷;
森林的先根遍歷對應於二叉樹的先序遍歷;
森林的中根遍歷對應於二叉樹的中序遍歷。
33. 寫算法求樹中結點的度;樹的度;樹中的葉子結點數;樹中的非終端結點數;樹中某結點的兄弟、祖先、子孫、層次、堂兄弟;樹的高度;森林中樹的數目。
考試時候大家默認為樹是二叉樹,減輕自己負擔又不會錯
求樹中結點的度:(孩子表示法)求樹的度只需要指針移動,度數遞增就好
樹的度:先把每個結點的度數求出來,再把所有結點的度數總和求出來就好啦
求樹的葉子結點的個數:(下面這個只是求二叉樹的)
int Leaf_Count(Bitree T)
{//求二叉樹中葉子結點的數目
if(!T) return 0; //空樹沒有葉子
else if(!T->lchild&&!T->rchild) return 1;
//葉子結點
else return Leaf_Count(T-lchild)+Leaf_Count(T-rchild);
//左子樹的葉子數加上右子樹的葉子數
}
求森林中樹的數目:就是右孩子循環過去,算出右孩子的數目,再加上本身根節點(即右孩子樹+1)
后面的其它的求的,自己應該能想出來
大致上很多都是用遞歸算法
34. Huffman樹能夠解決的問題是什么?圖示huffman編碼過程。
數據通信中的數據壓縮編碼問題

35. 如何設計Huffman編譯碼器最有效?
沒做出來,別問我(考這個就等死啦)
1.高頻率的短編碼 2.不要是別的編碼的前綴編碼
36. 何為完全圖、稀疏圖、稠密圖。
完全圖:對有向圖來說,邊數為n(n-1),對無向圖來說,邊數為n(n-1)/2
稀疏圖:有很少條邊的圖(e<<n )
稠密圖:有很多條邊的圖
37. 寫算法求無向圖中結點的度;有向圖中結點的入度和出度。
(這里只給思想,不給算法,鄰接矩陣存圖)
無向圖:鄰接矩陣的一行或一列的數值和,代表對應定點的度。
有向圖:鄰接矩陣的行代表對應頂點的出度,列代表入度。38. 圖的鄰接矩陣、鄰接表存貯結構各自的優缺點,適應的運算。
圖的數組表示法(鄰接矩陣表示法):二維數組存儲圖
優點:容易求各個頂點的度
缺點:當圖為稀疏圖時浪費空間
鄰接表表示法:
優點:容易找到第一個鄰接點和下一個鄰接點,
缺點:不方便找一個結點的入度
39. 最小代價生成樹的實際應用背景。
公路, 鐵路,通訊網等等實際問題的急需解決
例子:要在n個城市間建立通信聯絡網,
頂點——表示城市
權——城市間建立通信線路所需花費代價
希望找到一棵生成樹,它的每條邊上的權值之和(即建立
該通信網所需花費的總代價)最小———最小代價生成樹
40. 什么圖適合用Prim算法求最小代價生成樹,什么圖適合用 Kruskal算法求最小代價生成樹。
Prim算法適合求稠密的網的最小生成樹
kruskal適合求稀疏的網的最小生成樹
一般來說,當n>47時,用prim比較好!
41. 圖示用 Prim算法及 Kruskal算法求最小代價生成樹的過程。
(給出思想,圖自己根據思想或偽代碼演示)
方法一:普里姆(Prim)算法
——加點法,時間復雜度O(n2)
從某頂點開始,找其相鄰邊中權值最小的邊所連另一個頂點,再找與這兩個頂點相鄰邊中權值最小的邊所連第三個頂點,重復,擴展到所有頂點。

方法二:克魯斯卡爾(Kruskal)算法
——加邊法,時間復雜度與邊相關
先將所有頂點都看作無邊的非連通圖,選擇各頂點間最小邊做連通分量,直到所有頂點都在同一個連通分量上。

42. 舉例簡述“拓撲排序”所解決的實際問題。
流程圖,施工流程圖,課程決定的優先權
43. 請圖示“拓撲排序”的過程。
(給出思想,圖自己根據思想或偽代碼演示)
拓撲排序:由某個集合上的一個偏序得到該集合上的一個全序的操作。拓撲排序實際上是對鄰接表表示的圖進行深度優先遍歷的過程.
(具體自己舉個樹的例子,然后對其拓撲排序)
a.在有向圖中任選一個沒有前趨的頂點輸出;
b.從圖中刪除該頂點和所有以它為尾的弧;
c.重復上述a、b,直到全部頂點都已輸出,此時,頂點輸出序列即為一個拓朴有序序列; 或者直到圖中沒有無前趨的頂點為止。如果還有有前驅的頂點,此情形表明有向圖中存在環。


44. 舉例簡述“關鍵路徑”所解決的實際問題。
一個工程的並行的進行過程
(1) 完成整個工程至少需要多少時間;
(2) 哪些活動是影響工程的關鍵。
45. 最短路徑的兩個算法是什么?
迪傑斯特拉Dijkstra算法:求從某個源點到其余各頂點的最短路徑;
弗洛易德Floyd算法:求每一對頂點之間的最短路徑
46. 簡述靜態查找和動態查找?
靜態查找:基於線性表的查找
只對查找表進行查詢某個特定的數據元素或某個特定數據元素的各種屬性的操作。如:查詢成績表中是否有某學生或該學生某門課程的成績。
動態查找:基於樹的查找
對查找表進行查找,找不到就插入某個數據元素的操作。如:查找某個學生信息,找不到就插入。
47. 順序查找、折半查找、分塊查找算法適合的關鍵字結構和存貯結構。
順序查找:對存儲結構和關鍵字排列方式沒有特殊要求
折半查找:關鍵字整體有序,只適合順序存儲的有序表
分塊查找:關鍵字局部有序,即分塊有序,對存儲結構為順序和線性鏈表的均適用

48. 怎樣從二叉排序樹得到有序表。
中序遍歷
49. 已知長度為n 的表按表中元素順序構造平衡二叉排序樹,圖示構造過程。
提醒:得事先弄懂 LL型平衡旋轉 RR型平衡旋轉 LR型平衡旋轉 RL型平衡旋轉
在構造二叉排序樹的過程中,每當插入一個結點時,首先檢查是否因插入而破壞了樹的平衡性,如果是因插入結點而破壞了樹的平衡性,則找出其中最小不平衡子樹,在保持排序樹特性的前提下,調整最小不平衡子樹中各結點之間的連接關系,以達到新的平衡。通常將這樣得到的平衡二叉排序樹簡稱為AVL樹
50. 解釋構造平衡二叉排序樹的過程中做各種旋轉后仍能滿足二叉排序樹的特性。
利用大小順序來解釋
51. 各種查找算法的平均時間復雜度。
查找類型 平均時間復雜度
順序查找 O(n)
折半查找 O(Log2N)
分塊查找 O(n)-不確定原式為:1/2*(n/m+m)+1
52. 簡述Hash查找的構建過程。

53. 為一組關鍵字構造哈希函數並建立哈希表。
構造哈希函數的方法:直接定址法、數字分析法、平方取中法、折疊法、除留余數法、隨機數法
1. 哈希函數(散列函數):
把關鍵字key映射成記錄存貯地址的函數。
記做: d=H(key),
把哈希函數值d稱為K的哈希地址或散列地址。
2.哈希表:
假定有查找表:ht[0]~ht[n-1],
根據記錄的關鍵字K計算出d=H(key),以d為記錄地址,所構成的表叫做哈希表。
54. 指出希爾排序,歸並排序,快速排序,堆排序,基數排序中穩定的排序方法,並對不穩定的舉出反例。
選擇排序、快速排序、希爾排序、堆排序不是穩定的排序算法,
冒泡排序、插入排序、歸並排序和基數排序是穩定的排序算法。
55. 堆排序算法選用什么樣的存貯結構,按此算法得到的有序表是遞增還是遞減的。圖示建堆過程。
一維數組存儲,
小頂堆:遞增
大頂隊:遞減
56. 藉助於“比較”進行排序的算法在最壞情況下能達到的最好的時間復雜度是什么?

57. 指出直接插入排序,冒泡排序,快速排序, 堆排序,基數排序算法各適合的關鍵字結構。
直接插入排序:基本有序
冒泡排序:基本有序
歸並排序:多個排序表
快速排序:混亂的情況
堆排序:數據非常大
基數排序:多關鍵字排序
58. 指出各種排序算法的平均時間復雜度、最壞情況的時間復雜度。



