title: "PTA數據結構和答案解析"
author: Sun-Wind
date: January 8, 2022
背景:期末數據結構復習題
緒論和線性表
判斷題
The Fibonacci number sequence {F N } is defined as: F 0 =0, F 1 =1, F N =F N−1 +F N−2 , N=2, 3, .... The time complexity of the function which calculates F N recursively is Θ(N!).
F
根據遞推我們可以直到時間復雜度為O(N);
(logn)^2 is O(n).
T
之前對漸進時間復雜度理解有誤
An algorithm may or may not require input, but each algorithm is expected to produce at least one result as the output.
T
概念題
NlogN^2 and NlogN^3 have the same speed of growth
T
只有前面的系數常數不一樣,顯然正確
N2logN和NlogN2具有相同的增長速度。
F
顯然不對,一個系數是平方,一個是線性系數
2^N 和N^N 具有相同的增長速度
F
太簡單的咱就不說了哈
算法分析的兩個主要方面是時間復雜度和空間復雜度的分析
T
對於順序存儲的長度為N的線性表,訪問結點和增加結點的時間復雜度分別對應為O(1)和O(N)
T
若某線性表最常用的操作是存取任一指定序號的元素和在最后進行插入和刪除運算,則利用順序表存儲最節省時間。
T
對於順序存儲的長度為N的線性表,刪除第一個元素和插入最后一個元素的時間復雜度分別對應為O(1)和O(N)。
F
時間復雜度反了,刪除第一個元素線性表會把所有的元素向前移動
線性表L如果需要頻繁地進行不同下標元素的插入、刪除操作,此時選擇順序存儲結構更好。
F
鏈表更好
隊列的特性
隊列是后進先出的線性表。
F
隊列先進先出
具有N個結點的單鏈表中,訪問結點和增加結點的時間復雜度分別對應為O(1)和O(N)。
F
時間復雜度反了
將N個數據按照從小到大順序組織存放在一個單向鏈表中。如果采用二分查找,那么查找的平均時間復雜度是O(logN)。
F
線性表才是O(logN)
若用鏈表來表示一個線性表,則表中元素的地址一定是連續的。
F
鏈表 - 存儲結構
鏈表中邏輯上相鄰的元素,其物理位置也一定相鄰。
F
鏈表 - 存儲結構
鏈表是一種隨機存取的存儲結構。
F
線性表才是隨機存取
單選題
在數據結構中,從邏輯上可以把數據結構分成( )。
(1分)
A.動態結構和靜態結構
B.緊湊結構和非緊湊結構
C.線性結構和非線性結構
D.內部結構和外部結構
與數據元素本身的形式、內容、相對位置、個數無關的是數據的( )。
(1分)
A.存儲結構
B.存儲實現
C.邏輯結構
D.運算實現
數據的邏輯結構跟其相對位置無關
通常要求同一邏輯結構中的所有數據元素具有相同的特性,這意味着( )。
(1分)
A.數據在同一范圍內取值
B.不僅數據元素所包含的數據項的個數要相同,而且對應數據項的類型要一致
C.每個數據元素都一樣
D.數據元素所包含的數據項的個數要相等
以下數據結構中,( )是非線性數據結構。
(1分)
A.樹
B.字符串
C.隊列
D.棧
求整數n(n>=0)的階乘的算法如下,其時間復雜度為( )。
long fact(long n)
{
if (n<=1) return 1;
return n*fact(n-1);
}
A.Θ(log2^n)
B.Θ(n^2 )
C.Θ(n)
D.Θ(nlog2^n)
顯然遞歸n次
流程圖是描述算法的很好的工具,一般的流程圖中由幾種基本圖形組成。其中判斷框的圖形是
(1分)
A.菱形
B.長方形
C.平行四邊形
D.橢圓型
For the following function (where n>0)
int func ( int n )
{ int i = 1, sum = 0;
while ( sum < n ) { sum += i; i *= 2; }
return i;
}
A.O(logn)
B.O(n)
C.O(nlogn)
D.O(2^n)
因為有個i*=2
Suppose A is an array of length N with some random numbers. What is the time complexity of the following program in the worst case?
void function( int A[], int N ) {
int i, j = 0, cnt = 0;
for (i = 0; i < N; ++i) {
for (; j < N && A[j] <= A[i]; ++j);
cnt += j - i;
}
}
A.O(N^2)
B.O(NlogN)
C.O(N)
D.O(N^1.5 )
別漏掉第二個循環后面的;哦
在N個結點的順序表中,算法的時間復雜度為O(1)的操作是:
(2分)
A.問第i個結點(1≤i≤N)和求第i個結點的直接前驅(2≤i≤N)
B.在第i個結點后插入一個新結點(1≤i≤N)
C.刪除第i個結點(1≤i≤N)
D.將N個結點從小到大排序
注意是順序表
若某線性表最常用的操作是存取任一指定序號的元素和在最后進行插入和刪除運算,則利用哪種存儲方式最節省時間?
A.雙鏈表
B.單循環鏈表
C.帶頭結點的雙循環鏈表
D.順序表
注意是在最后進行插入和刪除
順序表中第一個元素的存儲地址是100,每個元素的長度為2,則第5個元素的地址是( )。
A.100
B.105
C.108
D.110
已知二維數組 A 按行優先方式存儲,每個元素占用 1 個存儲單元。若元素 A[0][0] 的存儲地址是 100,A[3][3] 的存儲地址是 220,則元素 A[5][5] 的存儲地址是:
A.295
B.300
C.301
D.306
220 - 4 = 216
從100 ~ 216 一共3行,每行39個元素
5*39+6+99 = 300
線性表若采用鏈式存儲結構時,要求內存中可用存儲單元的地址
A.必須是連續的
B.連續或不連續都可以
C.部分地址必須是連續的
D.一定是不連續的
將線性表La和Lb頭尾連接,要求時間復雜度為O(1),且占用輔助空間盡量小。應該使用哪種結構? (2)
A. 單鏈表
B. 單循環鏈表
C. 帶尾指針的單循環鏈表
D. 帶頭結點的雙循環鏈表
需要一個尾指針將后面那個節點連起來
對於一個具有N個結點的單鏈表,在給定值為x的結點后插入一個新結點的時間復雜度為
(2分)
A.O(1)
B.O(N/2)
C.O(N)
D.O(N 2 )
要先找到這個元素,然后再進行插入
將兩個結點數都為N且都從小到大有序的單向鏈表合並成一個從小到大有序的單向鏈表,那么可能的最少比較次數是:
(2分)
A.1
B.N
C.2N
D.NlogN
理想情況是某個鏈表的所有節點都比另一個鏈表的第一個節點小
已知表頭元素為c的單鏈表在內存中的存儲狀態如下表所示:
現將f存放於1014H處,並插入到單鏈表中,若f在邏輯上位於a和e之間,則a、e、f的“鏈接地址”依次是:(2分)
A.1010H, 1014H, 1004H
B.1010H, 1004H, 1014H
C.1014H, 1010H, 1004H
D.1014H, 1004H, 1010H
a要鏈接f的地址,e鏈接的地址不變,f鏈接到e的地址
多選題
非空線性表的結構特征
非空線性表具有哪些結構特征?
A.只有唯一的開始結點和唯一的終端結點
B.可擁有多個的開始結點和多個終端結
C.除開始結點外,每個結點只有一個前驅結點
D.除終端結點外,每個結點只有一個后繼結點
鏈表 - 時間復雜度
在包含n個數據元素的鏈表中,▁▁▁▁▁ 的時間復雜度為 $$O(n)$$。
A.訪問第 $$i$$ 個數據元素
B.在第 $$i \ (1 \leq i \leq n)$$ 個結點后插入一個新結點
C.刪除第 $$i \ (1 \leq i \leq n)$$ 個結點
D.將 $$n$$ 個元素按升序排序
棧和隊列
判斷題
序列{1,2,3,4,5}依次入棧,則不可能得到{3,4,1,2,5}的出棧序列
T
1不可能在2之前出棧
兩個棧共享一片連續空間,可以將兩個棧的棧底分別設在這片空間的兩端
T
Non recursive programs are generally faster than equivalent recursive programs. However, recursive programs are in general much simpler and easier to understand.
T
"Circular Queue" is defined to be a queue implemented by a circularly linked list or a circular array.
F
循環隊列是抽象數據類型,不局限於其實現的方式
單選題
現有隊列 Q 與棧 S,初始時 Q 中的元素依次是{ 1, 2, 3, 4, 5, 6 }(1在隊頭),S 為空。若允許下列3種操作:(1)出隊並輸出出隊元素;(2)出隊並將出隊元素入棧;(3)出棧並輸出出棧元素,則不能得到的輸出序列是:
A.1, 2, 5, 6, 4, 3
B.2, 3, 4, 5, 6, 1
C.3, 4, 5, 6, 1, 2
D.6, 5, 4, 3, 2, 1
A的操作是1122223333
B的操作是2111113
C的操作是221111 2應該在1的前面
D就是先全部入棧,然后全部輸出
循環隊列的引入,目的是為了克服( )。
(1分)
A.假溢出問題
B.真溢出問題
C.空間不夠用
D.操作不方便
循環隊列的隊滿條件為 ( )。(2分)
A.(sq.rear+1) % maxsize ==(sq.front+1) % maxsize
B.(sq.front+1) % maxsize ==sq.rear
C.(sq.rear+1) % maxsize ==sq.front
D.sq.rear ==sq.front
可以發現滿的時候其實還有一個位置空着
若采用帶頭、尾指針的單向鏈表表示一個堆棧,那么該堆棧的棧頂指針top應該如何設置?
(2分)
A.將鏈表頭設為top
B.將鏈表尾設為top
C.隨便哪端作為top都可以
D.鏈表頭、尾都不適合作為top
概念題
設有一順序棧S,元素s1,s2,s3,s4,s5,s6依次進棧,如果6個元素出棧的順序是s2,s3,s4, s6 , s5,s1,則棧的容量至少應該是( )。
(2分)
A.2
B.3
C.5
D.6
棧中最多只會有3個元素
線性表
判斷題
線性表中的所有數據元素的數據類型必須相同
T
KMP算法的特點是在模式匹配時指示主串的指針不會變小回溯。
T
關於非空線性表的前驅結點
非空線性表中每個結點都有一個前驅結點。
F
頭結點沒有前驅結點
關於非空線性表的開始結點
非空線性表可以有多個開始結點。
F
只能有一個開始結點
單選題
給定程序時間復雜度的遞推公式:T(1)=1,T(N)=2T(N/2)+N。則對該程序時間復雜度最接近的描述是:
A.O(logN)
B.O(N)
C.O(NlogN)
D.O(N^2)
利用數學進行遞推
T(N) = 2T(N/2) + N = 2 * 2 * T(N/4) + 2*N = ..... = 2^x * T(1) + x * N
其中x = log2N 所以原式子是N + NlogN
漸進時間復雜度是C
KMP算法下,長為n的字符串匹配長度為m的字串的時間復雜度為
(2分)
A.O(N)
B.O(M+N)
C.O(M+LOGN)
D.O(N+LOGM)
if ( A > B ) {
for ( i=0; i<N; i++ )
for ( j=N*N; j>i; j-- )
A += B;
}
else {
for ( i=0; i<N*2; i++ )
for ( j=N*2; j>i; j-- )
A += B;
}
時間復雜度是
A.O(N)
B.O(N^2 )
C.O(N^3 )
D.O(N^4 )
如果都執行第一個循環
是N^2 + N^2-1 + ....N^2-N = O(N^3);
第二個是2N,那更不用說了;
多選題
以下說法正確的是。
(2分)
A.求表長、定位這兩種運算在采用順序存儲結構時實現的效率不比采用鏈式存儲結構時實現的效率低
B.順序存儲的線性表可以隨機存取
C.由於順序存儲要求連續的存儲區域,所以在存儲管理上不夠靈活
D.線性表的鏈式存儲結構優於順序存儲結構
串,數組和廣義表
判斷題
假設模式串是abababaab,則KMP模式匹配算法中的next[j] = 0 1 1 2 3 4 5 6 2
T
想到這道題,我是真的無語
我發現書上寫的和在算法競賽里的next數組定義是不一樣的
而且書上的相當復雜,關鍵是PTA就是用的書上的內容
書上下標如果從0開始,
那么j=1時,就是-1,后面就是相等前后綴的大小,關鍵是next[j]指的是j前面的最大相等前后綴,也就是0~j-1
這樣的話就是-1 0 0 1 2 3 4 5 1
如果下標從1開始,那么每一個next都要向后移一位
算法競賽當中,next[j]指的就是從1~j的最大相等前后綴
其實兩者都能解決問題,但是書上定義的比較復雜
單選題
設主串 T = abaabaabcabaabc,模式串 S = abaabc,采用 KMP 算法進行模式匹配,到匹配成功時為止,在匹配過程中進行的單個字符間的比較次數是:
A.9
B.10
C.12
D.15
i
a b a a b a a b c a b a a b c
a b a a b c
j
到此為止是6次,然后j回溯
i
a b a a b a a b c a b a a b c
a b a a b c
j
之后再比較4次
總共10次
設廣義表L=((a,b,c)),則L的長度和深度分別為( )(2分)
A.1和1
B.1和3
C.1和2
D.2和3
由於在廣義表方面個人掌握的不是特別好,所以就多說一些
廣義表,又稱列表,也是一種線性存儲結構。
同數組類似,廣義表中既可以存儲不可再分的元素,也可以存儲廣義表,記作:
LS = (a1,a2,…,an)
其中,LS 代表廣義表的名稱,an 表示廣義表存儲的數據。廣義表中每個 ai 既可以代表單個元素,也可以代表另一個廣義表。
原子和子表
通常,廣義表中存儲的單個元素稱為 "原子",而存儲的廣義表稱為 "子表"。
例如創建一個廣義表 LS = {1,{1,2,3}},我們可以這樣解釋此廣義表的構成:廣義表 LS 存儲了一個原子 1 和子表 {1,2,3}。
以下是廣義表存儲數據的一些常用形式:
A = ():A 表示一個廣義表,只不過表是空的。
B = (e):廣義表 B 中只有一個原子 e。
C = (a,(b,c,d)) :廣義表 C 中有兩個元素,原子 a 和子表 (b,c,d)。
D = (A,B,C):廣義表 D 中存有 3 個子表,分別是A、B和C。這種表示方式等同於 D = ((),(e),(b,c,d)) 。
E = (a,E):廣義表 E 中有兩個元素,原子 a 和它本身。這是一個遞歸廣義表,等同於:E = (a,(a,(a,…)))。
注意,A = () 和 A = (()) 是不一樣的。前者是空表,而后者是包含一個子表的廣義表,只不過這個子表是空表。
廣義表的表頭和表尾
當廣義表不是空表時,稱第一個數據(原子或子表)為"表頭",剩下的數據構成的新廣義表為"表尾"。
強調一下,除非廣義表為空表,否則廣義表一定具有表頭和表尾,且廣義表的表尾一定是一個廣義表。
例如在廣義表中 LS={1,{1,2,3},5} 中,表頭為原子 1,表尾為子表 {1,2,3} 和原子 5 構成的廣義表,即 {{1,2,3},5}。
再比如,在廣義表 LS = {1} 中,表頭為原子 1 ,但由於廣義表中無表尾元素,因此該表的表尾是一個空表,用 {} 表示。
長度
廣義表的長度就是看第一層所含的元素個數
深度
廣義表的深度是max(每個元素深度) + 1
A=():A是一個空表,長度為0,深度為1
B=(e):B只有一個原子e,B的長度為1,深度為1
C=(a,(b,c,d)):C的長度為2,深度為2
D=(A,B,C)=((),(e),(a,(b,c,d))):D的長度為3,深度為3
E=(a,E):E是一個遞歸的表,長度為2,深度無限。
廣義表((a,b,c,d))的表頭、表尾是( )。
(2分)
A.表頭:a 表尾:(b,c,d)
B.表頭: ( ) 表尾:(a,b,c,d)
C.表頭:(a,b,c,d) 表尾:( )
D.表頭:(b,c,d) 表尾:(a)
對n階對稱矩陣壓縮存儲時,需要表長為( )的順序表。
(2分)
A.n/2
B.n×n/2
C.n(n+1)/2
D.n(n-1)/2
由於矩陣是對稱的,所以只需要儲存1+2+3+....+n = n(n+1)/2
有一個n×n的對稱矩陣A,將其下三角部分按行存放在一維數組B中,而A[0][0]存放於B[0]中,則第i行的對角元素A[i][i]存放於B中的( )處。
(2分)
A.(i+3)i/2
B.(i+1)i/2
C.(2n-i+1)i/2
D.(2n-i-1)i/2
[i][i]前面有i行,一共有1+2+....+i個元素,然后第i行第i個
總共是(1+i)i/2 + i + 1,由於下標從B[0]開始,剛開始算的時候是算了B[0]的
所以還要-1就是(i+3)i/2
二維數組 A 的每個元素是由 10 個字符組成的串,其行下標 i=0,1,…,8,列下標 j=1,2,…,10。若 A 按行序優先存儲,元素 A[8,5] 的起始地址與當 A 按列序優先存儲時的元素( )的起始地址相同。設每個字符占一個字節。
A.A[8,5]
B.A[3,10]
C.A[5,8]
D.A[0,9]
行序優先就是橫着存,列序優先就是豎着存,
行序優先是[8,5]那么這是810+5個元素;
對應的列序優先存儲是99+4
也就是A[3,10]
對於 C 語言的二維數組 int A[m][n],每個元素占 2 個字節,數組中元素 a[i,j]的存儲位置可由( )式確定。
(2分)
A.Loc[i, j]=A[m, n]+(n×i + j )×2
B.Loc[i, j]=Loc[0, 0]+[ (m+n)×i+j ]×2
C.Loc[i, j]=Loc[0, 0] + (n×i+j)×2
D.Loc[i, j]= (n×i+j)×2
數組 A[0..5, 0..6] 的每個元素占 5 個字節,將其按列優先次序存儲在起始地址為 1000 的內存單元中,則元素 A[5, 5] 的地址是( )。(2分)
A.1175
B.1180
C.1205
D.1210
(5*6+5 ) *5 = 175
這里指的是存儲的起始地址
稀疏矩陣一般的壓縮存儲方式有兩種,即()。(2)
A. 二維數組和三維數組
B. 三元組和散列
C. 三元組和十字鏈表
D. 替換為錯散列和十字鏈表誤項
設二維數組A[1… m,1… n]按行存儲在數組B中,則二維數組元素A[i,j]在一維數組B[1…m*n]中的下標為 ( )。(分)
A.n(i-1)+j
**B.n(i-1)+j-1**
C.i(j-1)
D.jm+i-1
這個題也是第二個我感到有點問題的題,按照道理來講應該選A的,但是答案選B
比如A[1][1]理論上應該在B[1]的,但是按照公式計算就是B[0]了
評論區如果有知道的小伙伴歡迎指出
帶行表的三元組表是稀疏矩陣的一種( )(2)
A. 順序存儲結構
B. 鏈式存儲結構
C. 索引存儲結構
D. 散列存儲結構
廣義表與稀疏矩陣都是線性表的擴展,它們的共同點為()。(2分)
A.都可以用鏈接結構與順序結構存儲
B.無共同點
C.都是遞歸結構
D.數據元素本身是一個數據結構
填空題
若串S=‘software’,其子串的數目是37
子串為單個字符有8個,2個字符有7個。。。。
一共是1+2+3+...8 = 36
由於空串也是子串,所以一共有37個子串
根據KMP算法,模式串p="abaabcac"各字符對應的失配值分別是
-1 0 0 1 1 2 0 1
這里根據書上,下標從0開始
設目標串text=“abccdcdccbaa”,模式串pattern=“cdcc”,若采用BF(Brute Force)算法,則在第6趟匹配成功。
第一趟
abcc~cdcc
第二趟
bccd~cdcc
依次類推
第六趟
cdcc~cdcc
若n為主串長度,m為模式串長度,采用BF(Brute Force)模式匹配算法,在最壞情況下需要的字符比較次數 (n-m+1)m
最壞情況下顯然是最后才匹配成功,那么前面(n-m)個字符每個字符都要比較m次,最后m個字符還要比較一次
設二維數組a[10][20],每個數組元素占用1個存儲單元,若按列優先順序存放數組元素,a[0][0]的存儲地址為200,則a[6][2]的存儲地址是多少?226
這題我其實也沒搞明白
按照列優先存儲,應該是 2*11+7+199 = 228才對
但是答案是226,評論區有知道的小伙伴歡迎留言
稀疏矩陣,即包含大量值為 0 的矩陣,此類矩陣的一種存儲方法是將矩陣中所有非 0 元素所在的位置(行標和列標)和元素值存儲在順序表(數組)中,通過存儲由所有非 0 元素的三元組構成的順序表,以及該稀疏矩陣的行數和列數,即可完成對整個稀疏矩陣的存儲,這就是稀疏矩陣使用三元組表示的實現思想。
因此,每個非 0 元素的三元組需要使用結構體進行自定義:
//三元組結構體
typedef struct {
int i,j;//行標i,列標j
int data;//元素值
}triple;
有一個100×90的稀疏矩陣,非0元素有10,設每個整型數占2個字節,則用三元組表示該矩陣時,所需的字節數是
66
將非零元素所在行、列、非零元素的值構成一個三元組(i,j,v) ;
對於該題:
每個非零元素占3 * 2 =6個字節,共10個非零元素,需610 = 60 個字節;
此外,還一般要用三個整數來存儲矩陣的行數、列數和總元素個數,又需要32 = 6個字節;
總共:60 + 6 = 66 個字節。
樹與二叉樹
判斷題
某二叉樹的前序和中序遍歷序列正好一樣,則該二叉樹中的任何結點一定都無右孩子。
F
前序是根左右,中序是左根右
應該是任何結點一定都沒有左孩子
存在一棵總共有2016個結點的二叉樹,其中有16個結點只有一個孩子
F
根據公式n0 = n2 + 1;
2016 - 16 = 2000 = 2n2 + 1;
顯然n2算出來是小數,所以不存在
關於哈夫曼樹
哈夫曼樹中一定沒有度為 1 的結點。
T
哈夫曼樹的特殊性質
- 哈夫曼樹中只有度為0和度為2的結點
非空二叉樹的形態
一棵非空二叉樹,若先序遍歷與后序遍歷的序列相反,則該二叉樹只有一個葉子結點。
T
已知一棵二叉樹的先序遍歷結果是ABC,則CAB不可能是中序遍歷結果。
T
分情況舉例討論
對於一個有N個結點、K條邊的森林,不能確定它共有幾棵樹
F
對一棵有N個結點的樹來說,顯然有N-1條邊
所以一共有N-K棵樹
哈夫曼編碼是一種最優的前綴碼。對一個給定的字符集及其字符頻率,其哈夫曼編碼不一定是唯一的,但是每個字符的哈夫曼碼的長度一定是唯一的。
F
哈夫曼每個字符的頻率相同時,碼長並不確定
單選題
設每個d叉樹的結點有d個指針指向子樹,有n個結點的d叉樹有多少空鏈域?
(1分)
A.nd
B.n(d−1)
C.n(d−1)+1
D.以上都不是
這里我們可以直接列舉一個例子,假設n = 3,d = 2
顯然空鏈域為4
這里只有C選項符合要求
某二叉樹的中序序列和后序序列正好相反,則該二叉樹一定是
(2分)
A.空或只有一個結點
B.高度等於其結點數
C.任一結點無左孩子
D.任一結點無右孩子
某二叉樹的前序和后序遍歷序列正好相反,則該二叉樹一定是
(1分)
A.空或只有一個結點
B.高度等於其結點數
C.任一結點無左孩子
D.任一結點無右孩子
如果A和B都是二叉樹的葉結點,那么下面判斷中哪個是對的?(3分)
A.存在一種二叉樹結構,其前序遍歷結果是…A…B…,而中序遍歷結果是…B…A…
B.存在一種二叉樹結構,其中序遍歷結果是…A…B…,而后序遍歷結果是…B…A…
C.存在一種二叉樹結構,其前序遍歷結果是…A…B…,而后序遍歷結果是…B…A…
D.以上三種都是錯的
先序中序后序是根據根結點而言的,葉子結點的相對順序保持不變
已知一棵完全二叉樹的第6層(設根為第1層)有8個葉結點,則該完全二叉樹的結點個數最多是:
(3分)
A.39
B.52
C.111
D.119
第六層有8個葉節點,所以第六層也是滿的。
假如第7層也滿了。那么總共有2^7-1個結點,也就是127個結點
由於8個結點沒有衍生出多余的16個結點
所以127-16 = 111
具有65個結點的完全二叉樹其深度為(根的深度為1):(3分)
A.8
B.7
C.6
D.5
由於65 = 64 - 1 + 2;
64 = 2 ^ 6;
所以一共6+1=7層
補充知識:線索二叉樹
對於一個有n個結點的二叉鏈表,每個節點都有指向左右孩子的兩個指針域,一共有2n個指針域。而n個結點的二叉樹又有n-1條分支線數(除了頭結點,每一條分支都指向一個結點),也就是存在2n-(n-1)=n+1個空指針域。這些指針域只是白白的浪費空間。因此, 可以用空鏈域來存放結點的前驅和后繼。線索二叉樹就是利用n+1個空鏈域來存放結點的前驅和后繼結點的信息。
如圖以中序二叉樹為例,我們可以把這顆二叉樹中所有空指針域的lchild,改為指向當前結點的前驅(灰色箭頭),把空指針域中的rchild,改為指向結點的后繼(綠色箭頭)。我們把指向前驅和后繼的指針叫做線索 ,加上線索的二叉樹就稱之為線索二叉樹。
設森林F中有三棵樹,第一、第二、第三棵樹的結點個數分別為M1 ,M2和M3。則與森林F對應的二叉樹根結點的右子樹上的結點個數是:(2分)
A.M1
B.M1+M2
C.M2+M3
D.M3
森林轉化為二叉樹,兄弟關系向右斜
對N(N≥2)個權值均不相同的字符構造哈夫曼樹。下列關於該哈夫曼樹的敘述中,錯誤的是:(2分)
A.樹中一定沒有度為1的結點
B.樹中兩個權值最小的結點一定是兄弟結點
C.樹中任一非葉結點的權值一定不小於下一層任一結點的權值
D.該樹一定是一棵完全二叉樹
哈夫曼樹不一定是完全二叉樹
設一段文本中包含字符{a, b, c, d, e},其出現頻率相應為{3, 2, 5, 1, 1}。則經過哈夫曼編碼后,文本所占字節數為:(2分)
A.40
B.36
C.25
D.12
畫出哈夫曼樹以后求出他的帶權路徑長度為4 * 1 + 4* 1 + 2 * 3+3 * 2 + 5 = 25
哈夫曼樹補充知識:
設一段文本中包含4個對象{a,b,c,d},其出現次數相應為{4,2,5,1},則該段文本的哈夫曼編碼比采用等長方式的編碼節省了多少位數?
A.0
B.2
C.4
D.5
等長方式編碼是什么
等長編碼要兩位(因為有4個對象)(00 01 10 11)再乘相應次數 = 等長編碼的總位數
所以等長編碼 = 2 * (4+2+5+1) = 24
畫出哈夫曼樹,帶權路徑長度為22
所以節約了2位數
具有1102個結點的完全二叉樹一定有__個葉子結點。
(3分)
A.79
B.551
C.1063
D.不確定
完全二叉樹的定義:二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的節點都連續集中在最左邊~
所以完全二叉樹度為1的結點要么是0,要么是1
根據n0 = n2 + 1
計算可得度為1的結點是1;
所以n0 = 551;
下面的函數PreOrderPrintLeaves(BinTree BT)按前序遍歷的順序打印出二叉樹BT的所有葉子結點。則下列哪條表達式應被填在空中?
void PreOrderPrintLeaves( BinTree BT )
{ if (BT) {
if (___________________) printf(" %d", BT->Data);
PreOrderPrintLeaves( BT->Left );
PreOrderPrintLeaves( BT->Right );
}
}
A.BT->Data != 0
B.!BT->Right
C.!BT->Left
D.!(BT->Left || BT->Right)
二叉樹的高度
若根節點為高度1,一棵具有 1025 個結點的二叉樹的高度為 ▁▁▁▁▁ 。
(1分)
A.10
B.11
C.11~1025 之間
D.10~1024 之間
已知字符集{ a, b, c, d, e, f },若各字符出現的次數分別為{ 6, 3, 8, 2, 10, 4 },則對應字符集中各字符的哈夫曼編碼可能是:(3分)
A.00, 1011, 01, 1010, 11, 100
B.00, 100, 110, 000, 0010, 01
C.10, 1011, 11, 0011, 00, 010
D.0011, 10, 11, 0010, 01, 000
隨便構建一棵哈夫曼樹,顯然只有b,d位於第四層,所以需要四位(xxxx)表示,並且bd的前三位(XXXx)應相同,而BCD選項中,bd的哈夫曼編碼前三不同,所以排除BCD。固選A
若將一棵樹 T 轉化為對應的二叉樹 BT,則下列對 BT 的遍歷中,其遍歷序列與 T 的后根遍歷序列相同的是:(2分)
A.先序遍歷
B.中序遍歷
C.后序遍歷
D.按層遍歷
對 n 個互不相同的符號進行哈夫曼編碼。若生成的哈夫曼樹共有 115 個結點,則 n 的值是:
(3分)
A.56
B.57
C.58
D.60
由於哈夫曼樹只有度為0和度為2的結點,115 = n2 + n2 + 1, n2 = 57,n0 = 58
二叉鏈表復習
以二叉鏈表作為二叉樹的存儲結構,在具有 n 個結點的二叉鏈表中(n>0),空鏈域的個數為 __(1分)
A.n+1
B.n
C.n−1
D.無法確定
每個結點都會對應一個頭指針,除了父節點,所以一共有N-1個非空鏈域,
一共有2N個鏈域,空鏈域是2N-N+1 = N+1
對於任意一棵高度為 5 且有 10 個結點的二叉樹,若采用順序存儲結構保存,每個結點占 1 個存儲單元(僅存放結點的數據信息),則存放該二叉樹需要的存儲單元的數量至少是:
(2分)
A.31
B.16
C.15
D.10
二叉樹的儲存要先按滿二叉樹分配即2^k-1個存儲單元
一棵度為4的樹T中,若有20個度為4的結點,10個度為3的結點,1個度為2的結點,10個度為1的結點,則樹T的葉子結點個數是( )。(2分)
A.41
B.82
C.113
D.122
和常規的公式推導一樣,n = n4+n3+n2+n1+n0 = 4n4+3n3+2n2+n1+1
所以n0 = 3n4+2n3+n2+1 = 82
若某二叉樹有 5 個葉結點,其權值分別為 10、12、16、21、30,則其最小的帶權路徑長度(WPL)是:
(1分)
A.89
B.200
C.208
D.289
這道題說白了也是求其哈夫曼樹帶權路徑長度
多選題
以下說法錯誤的是( )。(2分)
A.哈夫曼樹是帶權路徑長度最短的樹,路徑上權值較大的結點離根較近。
B.若一個二叉樹的樹葉是某子樹的中序遍歷序列中的第一個結點,則它必是該子樹的后序遍歷序列中的第一個結點
C.已知二叉樹的前序遍歷和后序遍歷序列並不能唯一確定這棵樹,因為不知道樹的根結點是哪一個。
D.在前序遍歷二叉樹的序列中,任何結點的子樹的所有結點都是直接跟在該結點之后。
圖
判斷題
無向連通圖所有頂點的度之和為偶數。
T
每條邊既是出度又是入度
無向連通圖邊數一定大於頂點個數減1。
F
成環就相等了
在任一有向圖中,所有頂點的入度之和等於所有頂點的出度之和。
T
如果無向圖G必須進行兩次廣度優先搜索才能訪問其所有頂點,則G中一定有回路。
F
一定有兩個連通分量
若圖G為連通圖且不存在拓撲排序序列,則圖G必有環。
T
拓撲序列和有環是充分必要條件
P 是頂點 S 到 T 的最短路徑,如果該圖中的所有路徑的權值都加 1,P 仍然是 S 到 T 的最短路徑。
F
單選題
若無向圖 G = (V, E) 中含 7 個頂點,則保證圖 G 在任何連邊方式下都是連通的,則需要的邊數最少是( )
A.6
B.15
C.16
D.21
如圖,6條邊不一定能使其連通,如果要讓7個頂點連通,首先要讓六個頂點完全連通,也就是說需要6*5/2條邊讓6個頂點完全連通,然后還剩下一條邊連第7個頂點
所以一共需要16條邊
具有5個頂點的有向完全圖有多少條弧?(2分)
A.10
B.16
C.20
D.25
注:任意兩個頂點之間都有兩條弧
如果G是一個有15條邊的非連通無向圖,那么該圖頂點個數最少為多少?
(3分)
A.7
B.8
C.9
D.10
首先頂點個數要盡可能少,那么就要用盡可能少的頂點數湊夠15條邊
最少要6個頂點湊夠,因為不能連通,所以至少需要6+1個頂點
具有 100 個頂點和 12 條邊的無向圖至多有多少個連通分量?(2分)
A.87
B.8
C.94
D.95
要讓連通分量盡可能地多,我們就要分配盡可能多地頂點,每個頂點都可以作為一個連通分量
所以要盡快湊齊前面的12條邊,需要6個頂點湊齊
還剩下94個頂點,成為94個連通分量,前面6個頂點單獨作為一個連通分量
一共95個連通分量
AOE網知識補充:
- 求出到達各個狀態的最早時間(按最大計)
這個過程是要從源點開始向匯點順推 - 求出到達各個狀態的最晚時間(按最小計)
這個過程是要從匯點開始向源點逆推
下圖所示的 AOE 網表示一項包含 8 個活動的工程。活動 d 的最早開始時間和最遲開始時間分別是:
(2分)
A.3 和 7
B.12 和 12
C.12 和 14
D.15 和 15
最早時間對應是
8-3
12-2
19-4
18-5
27-6
對於活動d,2的最早時間是12
最遲時間從匯點向源點遞推
所以27-6-7=14
查找
判斷題
在散列表中,所謂同義詞就是具有相同散列地址的兩個元素
T
經典概念題
若用平方探測法解決沖突,則插入新元素時,若散列表容量為質數,插入就一定可以成功。
F
使用平方探測法如果該位置已經有數可能會插入失敗
平方探測的整體流程
平方探測的整體流程和線性探測基本相似,但是線性探測是沒有③:
①根據哈希函數算出Hashval,i 初始化為零,判斷HashTable[Hashval]是否被占用,如果沒被占用,則Hashval就是根據哈希函數算出的值,跳出平方探測;如果被占用則向右探測(執行②);
②判斷HashTable[Hashval + i * i]是否被占用,如果沒被占用,則Hashval = Hashval + i * i,跳出平方探測;如果被占用則向左探測(執行③);
③判斷HashTable[Hashval - i * i]是否被占用,如果沒被占用,則Hashval = Hashval - i * i,跳出平方探測;如果被占用則i++繼續向右探測(執行②);
將M個元素存入用長度為S的數組表示的散列表,則該表的裝填因子為M/S。
T
裝填因子的概念
對包含N個元素的散列表進行查找,平均查找長度為:
(1分)
A.O(1)
B.O(logN)
C.O(N)
D.不確定
和這個散列表解決沖突的方式有關
設散列表的地址區間為[0,16],散列函數為H(Key)=Key%17。采用線性探測法處理沖突,並將關鍵字序列{ 26,25,72,38,8,18,59 }依次存儲到散列表中。元素59存放在散列表中的地址是:
(2分)
A.8
B.9
C.10
D.11
這里利用線性探測法,26%17 = 9,25%17 = 8,72 % 17 = 4,38 % 17 = 4,這里產生第一次沖突
所以38放到5這個位置,8產生第二次沖突,8放到10的位置
18%17 = 1,59 % 17 = 8,產生第三次沖突
所以59放到11的位置
將元素序列{18,23,11,20,2,7,27,33,42,15}按順序插入一個初始為空的、大小為11的散列表中。散列函數為:H(Key)=Key%11,采用線性探測法處理沖突。問:當第一次發現有沖突時,散列表的裝填因子大約是多少?
(2分)
A.0.27
B.0.45
C.0.64
D.0.73
注意這里是第一次發生沖突時,所以
18%11 = 7,23 % 11 = 1,11 % 11 = 0,20 % 11 = 9,2 % 11 = 2,7 % 11 = 7(這里發生第一次沖突)
所以此時的裝填因子是5/11 ~ 0.45
給定散列表大小為11,散列函數為H(Key)=Key%11。按照線性探測沖突解決策略連續插入散列值相同的4個元素。問:此時該散列表的平均不成功查找次數是多少?
A.1
B.4/11
C.21/11
D.不確定
此題也是經典題
查找成功的平均查找長度 = 比較次數之和/元素個數
查找失敗的平均查找長度 = 離空位的比較次數之和/模
0 1 2 3 4 5 .... 10
5 4 3 2 1 1 .... 1
所以5+4+3+2+1 + ... 1/11 = 21/11
每個空位還要單獨計算一次
從一個具有N個結點的單鏈表中查找其值等於X的結點時,在查找成功的情況下,需平均比較多少個結點?
(2分)
A.N/2
B.N
C.(N−1)/2
D.(N+1)/2
1+2+3+。。。+n=n*(n+1)/2;因此是(n+1)/2
給定輸入序列 {4371, 1323, 6173, 4199, 4344, 9679, 1989} 以及散列函數 h(X)=X%10。如果用大小為10的散列表,並且用分離鏈接法解決沖突,則輸入各項經散列后在表中的下標為:(-1表示相應的插入無法成功)
(2分)
A.1, 3, 3, 9, 4, 9, 9
B.1, 3, 4, 9, 7, 5, -1
C.1, 3, 4, 9, 5, 0, 8
D.1, 3, 4, 9, 5, 0, 2
分離鏈接法補充:
給定輸入序列 {4371, 1323, 6173, 4199, 4344, 9679, 1989} 以及散列函數 h(X)=X%10。如果用大小為10的散列表,並且用開放定址法以及一個二次散列函數h 2 (X)=7−(X%7)解決沖突,則輸入各項經散列后在表中的下標為:(-1表示相應的插入無法成功)
(2分)
A.1, 3, 3, 9, 4, 9, 9
B.1, 3, 4, 9, 7, 5, -1
C.1, 3, 4, 9, 5, 0, 8
D.1, 3, 4, 9, 5, 0, 2
開放定址法如下圖所示:
h2作為增量函數
若N個關鍵詞被散列映射到同一個單元,並且用分離鏈接法解決沖突,則找到這N個關鍵詞所用的比較次數為:
(2分)
A.N(N+1)/2
B.N(N−1)/2
C.N+1
D.N
找到第一個關鍵字用1次,第二個關鍵字用2次。。。
一共用1+2+3+...n = (1+n) * n / 2次
給定散列表大小為11,散列函數為H(Key)=Key%11。按照線性探測沖突解決策略連續插入散列值相同的5個元素。問:此時該散列表的平均不成功查找次數是多少?
(2分)
A.26/11
B.5/11
C.1
D.不確定
和之前的做法一樣,6+5+4+3+2+1+1+1+1+1+1/11 = 26/11;
現有長度為 7、初始為空的散列表HT,散列函數H(k)=k%7,用線性探測再散列法解決沖突。將關鍵字 22, 43, 15 依次插入到HT后,查找成功的平均查找長度是:
(2分)
A.1.5
B.1.6
C.2
D.3
這里計算查找成功,要注意是
22%7 = 1,43%7 = 1,15%7 = 1;
一共比較了1+2+3次,除以元素個數是6/3 = 2
設有一組關鍵字 { 92,81, 58,21,57,45,161,38,117 },散列函數為 h(key)=key%13,采用下列雙散列探測方法解決第 i 次沖突:h(key)=(h(key)+i×h 2 (key))%13,其中 h 2 (key)=(key%11)+1。試在 0 到 12 的散列地址空間中對該關鍵字序列構造散列表,則成功查找的平均查找長度為 __(2分)
A.1.6
B.1.56
C.1.44
D.1.33
這題我只能說,算的人都麻了好吧
92%13 = 1,比較一次
81%13 = 3,比較一次
58%13 = 6,比較一次
21%13 = 8, 比較一次
57%13 = 5,比較一次
45%13 = 6,產生沖突,h2(45) = 2
h(45) = 6+2=8,產生沖突
h(45) = 6+2*2 = 10,比較3次
161%13 = 5,產生沖突,h2(161) = 8
5+8%13 = 0;比較2次
38%13 = 12,比較一次
117%13 = 0,產生沖突,h2(117) = 8;
0+8 = 8,產生沖突
0+16%13 = 3,產生沖突
0+24%13 = 11,比較4次
一共比較了5+3+2+1+4 = 15;
15/9 = 1.6
已知一個長度為16的順序表L,其元素按關鍵字有序排列。若采用二分查找法查找一個L中不存在的元素,則關鍵字的比較次數最多是:
A.4
B.5
C.6
D.7
二分查找最壞比較次數是log2N + 1
填空題
假定查找有序表A[1..12]中每個元素的概率相等,則進行二分查找時的平均查找長度為37/12
可以唯一的標識一個記錄的關鍵字稱為主關鍵字。
直接定址法法構造的哈希函數肯定不會發生沖突。
哈希表是通過將查找碼按選定的
哈希函數和解決沖突的方法,把結點按查找碼轉換為地址進行存儲的線性表。哈希方法的關鍵是
選擇好的哈希函數和 處理沖突的方法。一個好的哈希函數其轉換地址應盡可能均勻,而且函數運算應盡可能簡單。
排序
判斷題
對N個記錄進行歸並排序,歸並趟數的數量級是O(NlogN)
F
數量級是O(logn);
要從50個鍵值中找出最大的3個值,選擇排序比堆排序快。
T
在數據量較小的情況下,選擇排序比堆排序要快一些
單選題
對N個記錄進行歸並排序,空間復雜度為:
(1分)
A.O(logN)
B.O(N)
C.O(NlogN)
D.O(N^2)
歸並排序的空間復雜度是O(N);
對N個記錄進行快速排序,在最壞的情況下,其時間復雜度是
(1分)
A.O(N)
B.O(NlogN)
C.O(N^2)
D.O(N^2logN)
快排的最壞時間復雜度是N^2
對於10個數的簡單選擇排序,最壞情況下需要交換元素的次數為:
(2分)
A.9
B.36
C.45
D.100
簡單選擇排序比較次數為O(N^2),移動次數為O(N);
將序列{ 2, 12, 16, 88, 5, 10, 34 }排序。若前2趟排序的結果如下:
第1趟排序后:2, 12, 16, 10, 5, 34, 88
第2趟排序后:2, 5, 10, 12, 16, 34, 88
則可能的排序算法是:
(2分)
A.冒泡排序
B.歸並排序
C.插入排序
D.快速排序
在內部排序時,若選擇了歸並排序而沒有選擇插入排序,則可能的理由是:
歸並排序的程序代碼更短
歸並排序占用的空間更少
歸並排序的運行效率更高
(2分)
A.僅 2
B.僅 3
C.僅 1、2
D.僅 1、3
對初始數據序列{ 8, 3, 9, 11, 2, 1, 4, 7, 5, 10, 6 }進行希爾排序。若第一趟排序結果為( 1, 3, 7, 5, 2, 6, 4, 9, 11, 10, 8 ),第二趟排序結果為( 1, 2, 6, 4, 3, 7, 5, 8, 11, 10, 9 ),則兩趟排序采用的增量(間隔)依次是:
(2分)
A.3, 1
B.3, 2
C.5, 2
D.5, 3
希爾排序具體做法參考之前寫的博客,這里不再贅述
快速排序方法在( )情況下最不利於發揮其長處。
(2分)
A.要排序的數據量太大
B.要排序的數據中含有多個相同值
C.要排序的數據個數為奇數
D.要排序的數據已基本有序
設一組初始記錄關鍵字序列(5,8,6,3,2),以第一個記錄關鍵字5為基准進行一趟從大到小快速排序的結果為( )。
(2分)
A.2,3,5,8,6
B.2,3,5,6,8
C.3,2,5,8,6
D.3,2,5,8,6
對序列{15,9,7,8,20,-1,4}進行排序,進行一趟后數據的排列變為{9,15,7,8,20,-1,4},則采用的是( )排序.
(2分)
A.選擇
B.希爾
C.直接插入
D.冒泡
如果是選擇排序,序列最后一定是最大或者最小的值,如果是希爾排序,那么序列變化一定是一組一組地變
如果是冒泡排序,最后一個數一定是最大最小值
綜上只有直接插入排序符合要求
對同一待排序序列分別進行折半插入排序和直接插入排序, 兩者之間可能的不同之處是____。
(2分)
A.排序的總趟數
B.元素的移動次數
C.使用輔助空間的數量
D.元素之間的比較次數
按排序過程中依據的原則分類,快速排序屬於( )
(2分)
A.插入類的排序方法
B.選擇類的排序方法
C.交換類的排序方法
D.歸並類的排序方法
排序過程中,對尚未確定最終位置的所有元素進行一遍處理稱為一“趟”。下列序列中,不可能是快速排序第二趟結果的是:
(2分)
A.5, 2, 16, 12, 28, 60, 32, 72
B.2, 16, 5, 28, 12, 60, 32, 72
C.2, 12, 16, 5, 28, 32, 72, 60
D.5, 2, 12, 28, 16, 32, 72, 60
以上就是PTA部分數據結構題目的答案和解析,有不正確的地方或者需要添加題解的地方歡迎在評論區指出
2022.1.12 更新了部分之前有問題的地方
一群只看不點贊的壞淫.....