線性表練習題

2021-10-05 03:13:53 字數 4407 閱讀 2016

題目(1):有序鍊錶的合併

將2個遞增的有序鍊錶合併為⼀乙個鍊錶的有序鍊錶; 要求結果鍊錶仍然使⽤用兩個鍊錶的儲存空間,不不另外佔⽤用其他的儲存空間. 表中不不允許有重複的資料。

演算法思想:

(1)假設待合併的鍊錶為la和lb,合併後的新錶使用頭指標lc(lc的表頭結點設為la的表頭結點)指向. pa 和 pb 分別是la,lb的工作指標.初始化為相應鍊錶的首元結點

(2)從首元結點開始比較, 當兩個鍊錶la 和lb 均未到達表尾結點時,依次摘取其中較小值重新鍊錶在lc表的最後.

(3)如果兩個表中的元素相等,只摘取la表中的元素,刪除lb表中的元素,這樣確保合併後表中無重複的元素;

(4)當乙個表達到表尾結點為空時,非空表的剩餘元素直接鏈結在lc表最後.

(5)最後釋放鍊錶lb的頭結點;

void

mergelist

(linklist *la, linklist *lb, linklist *lc)

else

if(pa->data > pb->data)

else

}//將非空表的剩餘元素之間鏈結在lc表的最後

pc->next = pa?pa:pb;

//釋放lb的頭結點

free

(*lb)

;}

題目(2):兩個鍊錶的交集

已知兩個鍊錶a和b分別表示兩個集合.其元素遞增排列列. 設計⼀乙個演算法,⽤用於求出a與b的交集,並

儲存在a鍊錶中; 例例如 : la = ; lb = ; lc = 。

演算法思想:

(1)假設待合併的鍊錶為la和lb,合併後的新錶使用頭指標lc(lc的表頭結點設為la的表頭結點)指向. pa 和 pb 分別是la,lb的工作指標.初始化為相應鍊錶的首元結點

(2)從首元結點開始比較, 當兩個鍊錶la 和lb 均未到達表尾結點時.

(3)如果兩個表中的元素相等,只摘取la表中的元素,刪除lb表中的元素;

(4)如果其中乙個表中的元素較小,刪除此表中較小的元素. 此表的工作指標後移;

(5)當鍊表la和lb有乙個先到達表尾結點為空時,依次刪除另乙個非空表中的所有元素,最後釋放鍊錶lb;

void

intersection

(linklist *la, linklist *lb, linklist *lc)

else

if(pa->data < pb->data)

else

}//lb為空,刪除非空表la中的所有元素

while

(pa)

//la為空,刪除非空表lb中的所有元素

while

(pb)

pc->next =

null

;free

(*lb)

;}

題目(3):鍊錶「原地旋轉」

設計⼀乙個演算法,將鍊錶中所有節點的鏈結⽅方向"原地旋轉",即要求僅僅利利⽤用原表的儲存空間. 換句句

話說,要求演算法空間複雜度為o(1); 例例如:l=, 逆轉後: l = ;

演算法思想:

(1)利用原有的頭結點*l,p為工作指標, 初始時p指向首元結點. 因為摘取的結點依次向前插入,為確保鍊錶尾部為空,初始時將頭結點的指標域置空;

(2)從前向後遍歷鍊錶,依次摘取結點,在摘取結點前需要用指標q記錄後繼結點,以防止鏈結後丟失後繼結點;

(3)將摘取的結點插入到頭結點之後,最後p指向新的待處理節點q(p=q);

void

inverse

(linklist *l)

}

題目(4):刪除鍊錶指定範圍的元素

設計⼀乙個演算法,刪除遞增有序鍊錶中值⼤大於等於mink且⼩小於等於maxk(mink,maxk是給定的兩個

引數,其值可以和表中的元素相同,也可以不不同)的所有元素;

演算法思想:

(1)查詢第乙個值大於mink的結點,用q指向該結點,pre 指向該結點的前驅結點;

(2)繼續向下遍歷鍊錶, 查詢第乙個值大於等於maxk的結點,用p指向該結點;

(3)修改下邊界前驅結點的指標域, 是其指向上邊界(pre->next = p);

(4)依次釋放待刪除結點的空間(介於pre和p之間的所有結點);

void

deleteminmax

(linklist *l,

int mink,

int maxk)

//2.查詢第乙個值大於等於maxk的結點

while

(p && p->data<=maxk)

//3.修改待刪除的結點指標

q = pre->next;

pre->next = p;

while

(q != p)

}

題目(5):鍊錶的指定範圍元素的逆置

設將n(n>1)個整數存放到⼀一維陣列r中, 試設計⼀乙個在時間和空間兩⽅方⾯面都盡可能⾼高效的演算法;將r

中儲存的串行列迴圈左移p個位置(0演算法思路:

先將n個資料原地逆置 9,8,7,6,5,4,3,2,1,0;

將n個資料拆解成[9,8,7,6,5,4,3] [2,1,0]

將前n-p個資料和後p個資料分別原地逆置; [3,4,5,6,7,8,9] [0,1,2]

複雜度分析:

時間複雜度: o(n); 時間複雜度:o(1);

void

reverse

(int

*pre,

int left ,

int right)

}void

leftshift

(int

*pre,

int n,

int p)

}

題目(6):找主元素(攻山頭)

已知⼀乙個整數串行列a = (a0,a1,a2,…an-1),其中(0<= ai <=n),(0<= i<=n). 若存在ap1= ap2 = …=

apm = x,且m>n/2(0<=pk演算法思路:

選取候選主元素, 從前向後依次掃瞄陣列中的每個整數, 假定第乙個整數為主元素,將其儲存在key中,計數為1. 若遇到下乙個整數仍然等於key,則計數加1. 否則計數減1. 當計數減到0時, 將遇到的下乙個整數儲存到key中, 計數重新記為1. 開始新一輪計數. 即可從當前位置開始重上述過程,直到將全部陣列元素掃瞄一遍;

判斷key中的元素是否是真正的主元素, 再次掃瞄陣列, 統計key中元素出現的次數,若大於n/2,則為主元素,否則,序列中不存在主元素;

演算法分析:

時間複雜度: o(n)

空間複雜度: o(1)

int

mainelement

(int

*a,int n)

else

else}}

//如果count >0

if(count >0)

//(6)判斷count>n/2, 確認key是不是主元素

if(count > n/2)

return key;

else

return-1

;//不存在主元素

}

題目(7):刪除絕對值相等的結點,僅保留第乙個

⽤用單鏈表儲存m個整數, 結點的結構為(data,link),且|data|<=n(n為正整數). 現在要去設計⼀乙個時間複雜度盡可能⾼高效的演算法. 對於鍊錶中的data 絕對值相等的結點, 僅保留留第⼀一次出現的結點,⽽而 刪除其餘絕對值相等的結點.例例如,鍊錶a = , 刪除後的鍊錶a=;

演算法思路:

申請大小為n+1的輔助陣列t並賦值初值為0;

從首元結點開始遍歷鍊錶,依次檢查t[|data|]的值, 若[|data|]為0,即結點首次出現,則保留該結點,並置t[|data|] = 1,若t[|data|]不為0,則將該結點從鍊錶中刪除.

複雜度分析:

時間複雜度: o(m),對長度為m的鍊錶進行一趟遍歷,則演算法時間複雜度為o(m);

空間複雜度: o(n)

void

deleteequalnode

(linklist *l,

int n)

//3.指標temp 指向首元結點

linklist temp =

(*l)

->next;

//4.遍歷鍊錶,直到temp = null;

while

(temp!=

null

)else

}}

線性表練習題2

題目要求 長度為n的順序表l,編寫乙個時間複雜度為o n 空間複雜度為o 1 的演算法,該演算法刪除線性表中所有值為x的資料元素。演算法分析 設定兩個計數器,乙個為i,記錄掃瞄過的元素的個數 乙個為j,記錄掃瞄過的非x的元素的個數。從1 n對所有的元素進行掃瞄,如果該元素不是x,則i j 並令i對應...

線性表練習題超詳細解答

天才亦是眾生,眾生皆懷其才。鍊錶練習 1有乙個帶頭結點的單鏈表l,設計乙個演算法使其元素遞增有序。演算法思想 用直接插入排序的方法,將鍊錶分成兩部分,每次取後部分乙個元素插入前部分正確的位置上。void sort linklist l p next pre next 待插元素歸位 pre next ...

線性表演算法題庫 線性表習題

鍊錶。若指標p指向某結點時,能夠根據該指標找到其直接後繼,能夠順後繼指標鏈找到p結點後的結點。但是由於不知道其頭指標,所以無法訪問到p指標指向的結點的直接前趨。因此無法刪去該結點。2.雙鏈表。由於這樣的鍊錶提供雙向指標,根據p結點的前趨指標和後繼指標可以查詢到其直接前趨和直接後繼,從而可以刪除該結點...