數據結構算法題目歸檔
一、順序表類
(1) 查找值
-
二分查找
-
編寫二分查找的遞歸算法
-
找出數組中未出現的最小正整數
(2) 刪除值
-
刪除所有值為x的值
-
刪除所有重復的值
-
刪除給定值 s 與 t 之間的所有元素
(3) 合並順序表
- 兩個有序順序表合並為一個新的有序順序表。
(4) 順序表內數據元素位置互換
-
一維數組 A[m+n] 中將兩個順序表m和順序表n 的位置互換
-
原地全部逆置
-
一維數組R的序列循環左移p個位置
-
刪除線性表 ai 和ai+n-1 共 n 個元素,並將之插入至原表中的第 j 個元素之前
-
設計將所有奇數移到所有偶數之前的算法
-
設計將所有負數均排在非負數之前的算法
-
編寫算法,以第一個元素為基准,將小於該元素的結點全部放到前面,大於該元素的結點全部放到其后。
-
設有一組初始記錄關鍵字序列 ( K1、K2、…、Kn ),要求設計一個算法能夠在 O(n) 的時間復雜度內將線性表划分成兩部分,其中左半部分的每個關鍵字均小於 Ki,右半部分的每個關鍵字均大於等於 Ki。
-
將一個數組最開始的若干個元素搬到數組的末尾,稱之為數組的旋轉。輸入一個已排好序數組的一個旋轉,求該旋轉數組的最小元素。如,數組 {3, 4, 5, 1, 2} 為有序數組{1, 2, 3, 4, 5}的一個旋轉數組,該數組的最小值為1。
(5) 其他
-
設計在順序存儲結構上實現裁剪字符串的算法。
-
已知 A=(a1, a2, …, am),B=(b1, b2, …, bn)均為順序表,試編寫一個比較 A¸B 大小的算法
-
在數組中,某個數字減去它右邊的數字得到一個數對之差。求所有數對之差的最大值。例如,在數組 {2, 4, 1, 16, 7, 5, 11, 9} 中,數對之差的最大值是 11,是 16 減去 5 的結果。
二、單鏈表類
1. 單個單鏈表算法題
(1) 刪除值
-
非遞增單鏈表,刪除值相同的多余結點
-
遞增單鏈表,刪除值相同的多余結點
-
不帶頭結點,刪除值為 x 的結點
-
帶頭結點,刪除值為x的結點
-
帶頭結點,刪除最小值
-
帶頭結點,刪除給定的兩個值之間的元素
-
帶頭結點的單鏈表保存 m 個整數,且 abs(data)<=n,(n為正整數), 對於鏈表中絕對值相等的結點,僅保留第一次出現的結點而刪除其余絕對值相等的結點
(2) 單鏈表內結點互換
-
帶頭結點,逆向輸出每個結點的值
-
帶頭結點,就地逆置
-
編寫算法要求按照輸入順序依次建立鏈表中各個結點
(3) 查找值
-
頭插法建立單鏈表
-
尾插法建立單鏈表
-
查找鏈表倒數第 k 個位置上的結點
-
帶頭結點,求單鏈表中的結點個數
(4) 單鏈表排序
-
帶頭結點,元素遞增有序
-
帶頭結點,遞增輸出元素,並釋放結點存儲空間
-
帶頭結點,循環單鏈表,遞增輸出元素,並釋放結點存儲空間直到表空,再刪除表頭結點
-
在鏈式結構上實現簡單選擇排序算法
-
判斷單鏈表中元素是否是遞增的算法
-
在鏈式存儲結構上設計直接插入排序算法。
(5) 其他
-
判斷帶頭結點的循環雙鏈表中心對稱
-
設單鏈表中有僅三類字符的數據元素(大寫字母、數字和其它字符),要求利用原單鏈表中結點空間設計出三個單鏈表的算法,使每個單鏈表只包含同類字符。
-
單鏈表有環,是指單鏈表的最后一個結點的指針指向了鏈表中的某個結點(通常單鏈表的最后一個結點的指針域是為空的)。試編寫算法判斷單鏈表是否存在環。
2. 多個單鏈表算法題
(5) 一個單鏈表分解 為兩個
-
將單鏈表A分解為以下這種形式:A表含有原表中序號為奇數的元素,B表中含有原表中序號為偶數的元素。
-
帶頭結點的單鏈表C={a1,b1,a2,b2······am,bn}拆解為兩個線性表,使得A={a1,a2···an},B = {bm,····b2,b1}。
-
已知集合A 和集合B存在,且分別帶頭結點的單鏈表L1 和 L2表示。編寫算法實現集合運算: A = A - B
(6) 兩個單鏈表歸並為一個
-
兩個遞增的單鏈表歸並為一個遞減的單鏈表,並要求利用原來兩個單鏈表的結點存放歸並后的單鏈表。
-
兩個有序單鏈表A和B的合並排序,可以把合並后的結果放在單鏈表C中。
-
找出兩個鏈表的公共結點,輸出是一條新的鏈表。
-
找出兩個鏈表的公共結點的起始位置,輸出是一個整數值。
-
帶頭結點且遞增有序的單鏈表A和B,找出兩個鏈表的公共元素值並存於單鏈表C中。
-
遞增有序的單鏈表A和B,找出兩個鏈表的公共元素存放於A鏈表中。
-
將循環單鏈表h2鏈接到h1之后,要求鏈接后的鏈表仍保持循環鏈表形式
(7) 一個單鏈表與另一個單鏈表的關系
- 判斷單鏈表B中的序列是否是單鏈表A中序列的連續子序列
三、樹和二叉樹類
(1) 樹的遞歸遍歷
-
計算一棵給定二叉樹的所有雙分支結點個數
-
編寫二叉樹B中所有結點的左、右子樹進行交換的函數
-
求先序遍歷序列中第 k (1<=k<=二叉樹中結點個數) 個結點的值
-
刪除以元素值為x為根的子樹
-
已知滿二叉樹的先序序列,求其后后序序列
-
判斷兩棵二叉樹是否相同的算法
-
給定的表達式(二叉樹)轉換為等價的中綴表達式並輸出
-
復制二叉樹
-
設樹的存儲結構為孩子鏈表表示法。試編寫一遞歸的先根遍歷樹的算法。
-
若在一棵已知的二叉樹 T 中存在數據元素為 e1的結點,則刪除該結點的右子樹p;若存在數據元素為 e2的結點且該結點無右子樹,則將 p插入為該結點的右子樹。
(2) 樹的結點相關
-
查找值為 x 的結點及其所有祖先
-
查找值為 j結點x在二叉樹中的雙親結點算法
-
查找二叉樹中某個結點x
-
指針p(非空)指向二叉樹中的某個結點,試寫出求p所指結點的中序后繼的算法
-
查找二叉樹中任意兩個結點的最近公共祖先
-
統計以孩子兄弟表示法存儲的森林的葉子結點數
-
統計以孩子兄弟表示法存儲的樹的葉子結點數
-
統計二叉樹中度為 1 結點個數和度為 2 的結點個數
-
統計二叉樹中度為 1 的結點數目,輸出二叉樹中所有的葉子結點
-
設計一個算法求其指定的某一層 k(k>1)的葉子結點個數
-
設計統計二叉樹中所有結點值之和的算法
-
設計統計二叉樹中所有結點數量的算法
-
設計統計二叉樹中結點值為x的結點個數
(3) 求二叉樹的高度或者寬度
-
非遞歸算法求二叉樹的高度
-
遞歸算法求二叉樹的高度
-
求非空二叉樹b的寬度 (即具有結點數最多的那一層的結點個數)
-
以孩子兄弟鏈表為存儲結構,請設計遞歸算法求樹的深度
-
求二叉樹中以元素值為 x 的結點為根的子樹的深度
-
求森林的深度
(4) 樹的非遞歸遍歷
-
后序遍歷二叉樹的非遞歸算法
-
先序遍歷非遞歸算法
-
中序遍歷非遞歸算法
-
層次遍歷算法 (無要求非遞歸)
-
編寫算法要求不用遞歸也不用棧,返回二叉樹T的后序序列中的第一個結點的指針
(5) 樹的存儲方法
-
建立一棵二叉樹,要求以二叉鏈表存儲結構存儲
-
根據先序遍歷和中序遍歷建立二叉樹
-
按給定的表達式建相應二叉樹
-
判別給定二叉樹是否是完全二叉樹的算法
-
二叉樹的葉結點連成一個單鏈表
-
已知一棵樹的層次序列及每個結點的度,編寫算法構造此時的以孩子兄弟鏈表為存儲結構的樹
-
以孩子兄弟鏈表為存儲結構的樹,編寫算法,按(雙親、孩子)格式輸出樹中所有的邊
樹的應用
(6) 線索二叉樹
-
在中序線索樹 root 找出 x 結點的后繼結點
-
在中序線索樹 root 找出 q 所指結點的后繼結點
-
在前序線索樹中找出x結點的后繼結點
-
編寫實現二叉樹后序線索化的算法
(7) 哈夫曼二叉樹
-
求二叉樹T的WPL的算法
(8) 二叉排序樹
-
根據一組非零的整數序列建立一棵二叉排序樹算法
-
判斷給定的二叉樹是否是二叉排序樹
-
指定結點在給定二叉排序樹中的層次
-
求出給定二又排序樹中最小和最大的關鍵字
-
設計一個算法,從小到大輸出二叉排序樹中所有值小於 k 的關鍵字
-
在二叉排序樹中查找關鍵字為key的結點。若找到,返回該結點的地址;否則返回NULL。
-
給出按由小到大順序輸出此二叉排序樹中結點值的算法
-
編寫一個遞歸算法,二又排序樹上查找第k (1<k<n) 小的元素,並返回指向該結點的指針。要求算法的平均時間復雜度為O(log2n),二又排序樹的每個結點中除data、lchild、rchild等數據成員外,增加一個count成員,保存以該結點為根的子樹上的結點個數。
(9) 平衡二叉樹
-
判斷二叉樹是否平衡二叉樹的算法
-
使用遞歸方法,求各結點的平衡因子並輸出
四、圖類
(1) 圖的存儲結構和基本操作
-
寫出從圖的鄰接表表示轉換成鄰接矩陣表示的算法
-
由依次輸入的頂點數、弧數和各頂點信息、弧信息建立有向圖的鄰接表存儲結構
-
設有向圖的十字鏈表存儲結構定義如下,試分別編寫求圖中頂點 i 的出度和入度的算法
-
寫一建立圖的鄰接多重表存儲結構的函數
-
已知某無向圖采用鄰接表作為存儲結構。寫一函數,刪除圖中的某一頂點 Vi 。
(2) 圖的遍歷
-
判斷一個無向圖G是否為一棵樹
-
編寫算法,判斷鄰接表表示的無向圖是否是連通圖(每一對結點均有路徑相連)
-
寫出圖的深度優先搜索DFS算法的非遞歸算法
-
無向圖采用鄰接表方式存儲,編寫出廣度優先遍歷訪問的算法
-
求無向圖 G 的連通分量的算法。要求輸出每一連通分量的頂點值。
-
無向圖采用鄰接表結構存儲,要求按廣度優先搜索統計連通子圖的個數,並輸出所有連通子圖的生成樹
-
無向圖采用鄰接表結構存儲,要求按深度優先搜索統計連通子圖的個數,並輸出所有連通子圖的生成樹
(3) 圖的路徑
-
判斷以鄰接表方式存儲的有向圖中是否存在由頂點 vi 到頂點 vj 的路徑,采用基於深度優先遍歷判斷
-
判斷以鄰接表方式存儲的有向圖中是否存在由頂點 vi 到頂點 vj 的路徑,采用基於廣度優先遍歷判斷
-
輸出從頂點 Vi 到頂點Vj 的所有簡單路徑
-
已知有N個結點的無向圖要求由根開始逐層輸出連通子圖中所有生成樹中的各條邊,邊輸出格式為 ( Ki ,Kj )
-
編寫算法求有向圖G中距離頂點V0 簡單路徑長度為 len 的所有頂點
(4) 圖的拓撲序列
-
某有向圖采用鄰接表存儲,編寫算法輸出該圖的拓撲序列。
-
寫一算法,判斷有向圖是否有回路。
(5) 圖的應用
- 求最小生成樹的算法,從N = (V,{E})中逐步去掉不合適的邊,最終形成最小生成樹,試設計這樣的算法。
五、查找類
(1) 順序查找和折半查找
-
寫出折半查找的遞歸算法
-
按折半查找給定值為 key 的元素
(2) 哈希表
-
某關鍵字序列按除留余數法構建了哈希表,H(key) = key%P (P小於等於m),采用線性探測再散列解決沖突。編寫算法,對給定長度為m、元素個數為 n 的哈希表(m大於等於n),計算等概率情況下查找成功的平均查找長度。
-
編寫算法,依次輸入n個整數,構造哈希表。哈希函數是除留余數法,處理沖突的方法采用線性探測再散列(假設表長是m,p是小於或等於m的最大質數)
-
編寫算法,為依次輸入的 n 個元素構造哈希表,H(x) 為哈希函數,以線性探測再散列解決沖突。
(3) 其他
- 線性表中各結點的檢索概率不等時,可用如下策略提高順序檢索的效率:若找到指定的結點,則將該結點和其前驅結點(若存在)交換,使得經常被檢索的結點盡量位於表的前端。試設計在順序結構和鏈式結構的線性表上實現上述策略的順序檢索算法。
六、排序類
(1) 冒泡排序
- 雙向冒泡排序算法
(2) 快速排序
-
試編寫一個算法,使之能夠在數組L[1..n]中找出第 k 小的元素
-
編寫非遞歸的快速排序算法
-
找第k項.n個元素的第k項是把它們從小到大的排序后的第k個元素.如 (16,12,99,95,18,87,10)的第4項是18.假定n個整數放在數組a[1..n]中,試寫一算法,不經對整個數組排序,找到第 k 項。並寫出此算法在最好和最壞情況下的時間復雜度.(提示,利用快速排序中的划分方法)
(3) 堆排序
-
設關鍵字序列 ( K1、K2、…、Kn-1 ) 是堆,設計算法將關鍵字序列 ( K1、K2、…、Kn-1、X ) 調整為堆。
-
假設待排序的 n 個元素存放在數據 a[1···n]中,利用堆排序算法對 n 個元素進行升序排序。
(4) 直接插入排序
-
設順序表用數組A[]表示,表中元素存儲在數組下標1~m+n的范圍內,前m個元素遞增有序,后n個元素遞增有序,設計一個算法,使得整個順序表有序
-
在鏈式存儲結構上設計直接插入排序算法。
(5) 簡單選擇排序
- 編寫一個算法,在基於單鏈表表示的待排序關鍵字序列上進行簡單選擇排序。
(6) 歸並排序
- 請采用遞歸方式實現二路歸並排序程序MergeSort(data,first,last),在O(nlogn) 時間內完成排序,以數組D={8,6,4,10,5,3,7,18}為例,分析給出函數每一次遞歸調用的具體參數和順序,以及對應的系統棧中的變化情況。
(6) 不能確定
-
荷蘭國旗問題:設有一個僅由紅、白、藍三種顏色的條塊組成的條塊序列,請編寫一個時間復雜度為O(n)的算法,使得這些條塊按紅、白、藍的順序排好,即排成荷蘭國旗圖案。
-
已知線性表按順序存儲,且每個元素都是不相同的整數型元素,設計把所有奇數移動到所有偶數前邊的算法(要求時間最少,輔助空間最少)。
-
欲有一個數組中存放了一個無序的關鍵序列K1、K2、···Kn。現要求將 Kn放在元素排序后的正確位置上,試編寫實現該功能的算法,要求比較關鍵字的次數不超過 n 。
-
設有順序 n 個盒子,每個盒子有一個小球,每個小球的顏色是紅、白、藍之一。要求重新安排這些小球,使得所有紅色小球在前,所有白色小球居中,所有藍色小球居后,重新安排時對每個小球的顏色只能看一次,並且只允許交換操作來調整小球的位置。
-
欲用四種顏色對地圖上的國家塗色,有相鄰邊界的國家不能用同一種顏色。
七、 棧和隊列及循環鏈表
(1) 隊的出隊入隊
-
要求循環隊列不損失一個空間全部都能得到利用,設置一個標志域tag,以tag為0或1來區分頭尾指針相同時的列狀態的空與滿,請編寫與此結構相應的出隊算法。
-
設以順序存儲結構的循環隊列的front 和 rear分別指示循環隊列中隊頭和隊尾元素,試寫出相應的入隊列和出隊列的算法。
(2) 循環雙鏈表
-
有一個帶有頭結點的循環雙鏈表,表頭指針為head,結點有四個域,data,flreg,llink,rlink,其中flreg記錄結點數據的訪問次數。假定鏈表的結點已按訪問次數不增序排列。寫一算法查找鏈表中是否有值為x的結點,如有,則讓該結點的訪問次數加1,並且要使鏈表仍保持不增序,如沒有,則不作任何工作。
-
設有一個帶頭結點的、按元素值遞減有序排列的雙向循環列表,編寫算法,插入一個元素並保持其有序性。
-
試設計將單向循環鏈表變為雙向循環鏈表的算法
(3) 棧的應用
-
判別讀入的字符序列是否為“回文”。
-
識別讀入的一個字符序列是否為反對稱的字符序列。
-
括號匹配的檢驗
-
若棧結構的存儲采用帶頭結點的單鏈表實現,寫出鏈棧的初始化、入棧和出棧的過程。
-
已知圖兩個棧S1,S2共享順序存儲空間 A[1···K],S1的棧底在 A[1]處,S2的棧底在A[K]處,試編寫S1和S2的入棧算法和出棧算法。
-
請設計合理算法,在 O(n) 時間復雜度條件下,將中綴式a + 3b + 4(c-d)轉化為對應的后綴表式並計算出表達式的值,若a=1,b=2,c=4,d=3,給出計算結果
(4) 循環單鏈表
- 寫一算法,對一帶頭結點且僅設隊尾指針的鏈式循環隊列就地逆置