資料結構測試題錯題歸納 1~10
一
int a[5][4], (*p)[4]=a;,陣列a的首地址為100,*(p+2)+3等於 ( )
- A 116
- B 118
- C 144
- D 122
錯誤思路:(*p)[4]展開成 *(p+0)+4 就是 p+0*4+4 = p+4 = a 地址是100;*(p+2)+3展開成 p+2*4+3 = p+8+3 = p+11 ,與p+4相差7個int單元,就是 7*4個位元組 ,最終地址是100+7*4 = 128。
分析:沒有搞清楚指標p定義時賦值的格式,自己誤把 (*p)[4]看作陣列首地址a。
正確思路:指標p是一個二級指標,int (*p)[4]=a;表示將p指向a這個二級地址,p表示的地址是100。*(p+2)+3展開成 p+2*4+3 = p+8+3 = p+11 ,與p相差11個int單元,就是 7*11個位元組,最終是地址是144(在32位作業系統中int長度為32個bit)。答案選C。
二
問:已知元素的入棧順序為abcde,則下列哪種出棧順序是不可能的(出棧和入棧操作可交叉進行)
- A.edcba
- B.cabde
- C.dcbae
- D.bcdea
分析:出棧和入棧操作可交叉進行,說明入棧操作並不一定是連續進行的。由於棧有後入先出的邏輯特點,所以對於該題有如下規律:出棧的第一個元素是在原來的次序中是第幾個,那麼他的前面的元素必然都還在棧中。比如c先出棧,說明此時ba已經入棧且一定還在棧中
正確思路:
A選項:e先出棧,說明棧中存在元素 d-c-b-a 。正確!
B選項:c先出棧,棧中存在 b-a ,元素b距離棧頂比較近。錯誤
C選項:d先出棧,棧中存在 c-b-a,正確。
D選項:b先出棧,棧中存在 a,正確。
三
問:若二維陣列 a 有 m 列,則在陣列元素 a[i][j] 前的元素個數為()
- A. j * m + i
- B. i * m + j
- C. i * m + j - 1
- D. j * m + i - 1
錯誤思路:a[i][j] 表示第i行第j列個元素, a[i][j] 表示第 i*m+j 個元素,除去本身前面有 i*m+j-1 個元素。
錯誤分析:沒有考慮到陣列的下標是從0開始的,a[i][0] a[i][1] a[i][2] ....
正確思路:a[i][j] 表示第i行第j列個元素。第i行上有 0 1 2....(i-1)行,共有i行 ,就是i*m個元素;第j列前面有 0 1 2....(j-1)個列,就是j個元素。一共算下來就是 i*m+j 個,選擇B
四
問:在一個完全二叉樹中,編號為i的節點存在左孩子,則左孩子的編號是( )設根節點編號為0
- A 2i
- B 2i - 1
- C 2i +1
- D 2i + 2
錯誤思路:
假設i節點是j層 最後一個節點
深度為j:i = 2^j -1 個節點
深度為j+1 : 2^(j+1) -1 = (i+1)*2 -1 個節點
此時,(i+1)*2 -1 代表第j+1層的最後一個節點(屬於i節點的右孩子)
因為根節點編號是0開始計算,又因為是i節點的左孩子。結果是(i+1)*2 -1 -1 -1 = 2i -1
錯誤分析:因為題目給的是節點編號i,所以把i直接當成"2^j -1"節點個數是不正確滴~ 這是一到找規律的題目,簡單做法就是把數值代進入驗證每個選項。也可以嘗試邏輯推理(上面就是這種方法,,失敗了 -_-||)
正確思路:
1.簡單的判斷:因為根節點的編號是0,它的左子節點是1.帶入4個選項就可以輕輕鬆鬆的選出正確答案C...
2.推理判斷:
假設i節點是j層 最後一個節點
深度為j:i+1 = 2^j -1 個節點
深度為j+1 : 2^(j+1) -1 = (i+2)*2 -1 個節點
此時,(i+2)*2 -1 代表第j+1層的最後一個節點(屬於i節點的右孩子)
因為根節點編號是0開始計算,又因為是i節點的左孩子。結果是(i+2)*2 -1 -1 -1 = 2i +1
五
深度為k的完全二叉樹中,最少有( )個節點
A 2^(k-1)-1
B 2^(k-1)
C 2^(k-1)+1
D 2^(k-)
錯誤思路:深度為k的滿二叉樹有2^k 個節點,也就是說深度為k-1的滿二叉樹有2^(k-1)個節點。至少再加一個節點 2^(k-1) +1 個構成深度為k的完全二叉樹
分析:這裡是公式弄錯了,深度為k的滿二叉樹有2^k-1個節點,,這個可證明的...
正確思路:深度為k的滿二叉樹有2^k - 1 個節點,也就是說深度為k-1的滿二叉樹有2^(k-1) - 1 個節點。至少再加一個節點 2^(k-1) -1 +1 個構成深度為k的完全二叉樹。所以選C。
六
問:若用一個大小為 6 的陣列來實現迴圈佇列,且當 rear 和 front 的值分別為 0 和 3 。當從佇列中刪除一個元素,再加入兩個元素後, rear 和 front 的值分別為 。
- A. 1和5
- B. 2和4
- C. 4和2
- D. 5和1
錯誤思路:把隊頭和隊尾搞反了(以為陣列下標小的就是隊頭,在對尾的前面)
分析:這是一個迴圈佇列,rear表示隊尾 front表示隊頭。方向是 0(rear) - 5 - 4 - 3(rear) - 2 - 1...
正確思路:在佇列中,出隊,頭指標向隊尾方向偏移1;入隊,尾指標向同樣的方向加1。也就是,刪除一個元素 front+1=4 再加入兩個元素後 rear+2=2。選B
七
在程式設計中,要對兩個16K×16K的多精度浮點數二維陣列進行矩陣求和時,行優先讀取和列優先讀取的區別是()
- A. 沒區別
- B. 行優先快
- C. 列優先快
- D. 2種讀取方式速度為隨機值,無法判斷
正確思路:二維陣列預設是行優先儲存,在記憶體中每行資料的儲存是連續的,而每列的資料不是連續的。按行讀取只要每讀一個數據地址偏移一下,要是按照列來讀取還有根據下標來計算當前儲存位置再讀取。所以按行讀取的速度更快些
八
若某線性表最常用得操作是存取任一指定序號的元素和在最後進行插入和刪除運算,則利用哪種儲存方式最節省時間?
- A. 順序表
- B. 雙鏈表
- C. 帶頭結點的雙迴圈連結串列
- D. 單迴圈連結串列
錯誤思路:根據連結串列方便進行插入和刪除節點的特性,選擇了D
分析與正確思路:順序表適合存取序號位置的元素,對任意位置存取最方便的就是陣列了;在最後進行插入啥刪除運算,也不用涉及表中元素節點進行位移的額外操作。選擇A。
九
假設有60行70列的二維陣列A[1……60,1…70]以列序為主序順序儲存,其基地址為10000,每個素佔2個儲存單元,那麼第32行第58列的元素A[32,58]的儲存地址為( )。(無第0行第0列元素)
- A. 16902
- B. 16904
- C. 14454
- D. 其它選項均不對
錯誤思路:先計算A[32][58]前面有多少個元素,因為是陣列下標從1開始計算的,A[32][58]前面應該有(32-1)行(58-1)列。31*70+57=2227個元素,一共有2227*2=4454個儲存單元。加上基地址,4454+10000=14454
分析:以列序為主序順序儲存....而我上面是按照行為主序計算的。
正確思路:先計算A[32][58]前面有多少個元素,該陣列是按照列為主序順序儲存,也就是陣列列元素上的資料是地址相鄰的。因為是陣列下標從1開始計算的,A[32][58]前面應該有(32-1)行(58-1)列。31+57*60=3451個元素,一共有3451*2=6902個儲存單元。加上基地址,6902+10000=16902。故選A
十
若陣列S[1..n]作為兩個棧S1和S2的儲存空間,對任何一個棧,只有當[1..n]全滿時才不能進行進棧操作。為這兩個棧分配空間的最佳方案是()
- A. S1的棧底位置為0,S2的棧底位置為n+1
- B. S1的棧底位置為0,S2的棧底位置為n/2
- C. S1的棧底位置為1,S2的棧底位置為n
- D. S1的棧底位置為1,S2的棧底位置為1
正確思路:由於棧的操作都是在棧頂一端進行,根據"只有當[1..n]全滿時才不能進行進棧操作"這個條件,S1棧底設定在陣列的0位置,向上(陣列索引增加方向)進行壓棧;S2棧底設定在陣列的n位置,向下(陣列索引減少方向)進行壓棧。可以實現空間的最大利用,選C。