數據結構期末自測題


數據結構自測題

1.簡述數據結構的概念。(4個點)
數據結構是計算機存儲,組織數據的方式,是指相互之間存在一種或多種特定關系的數據的集合。
存儲:值存儲在數據中,值按照性質歸類於數據項,按照個體歸類於數據元素,數據項與數據元素的特定組合構成數據結構,整體統稱為數據對象。

2.G={<k1,k3>,<k1,k8>,<k2,k3>,<k2,k4>,<k2,k5>,<k3,k9>,<k5,k6>,<k8,k9>,<k9,k7>,<k4,k7>,<k4,k6>}, <a,b>表示一條邊的起點與終點,求該圖的開始起點與結束終點。
畫圖求解
開始起點:1, 2
結束終點:6, 7

3.簡述空間復雜度概念。
程序在運行過程中臨時變量占用空間的大小。

4.根據表格整理出鏈表數據的正確順序。
image

Ren->Zhi->Chu->Xing->Ben->Shan

5.說明循環單鏈表與單鏈表,循環雙鏈表與雙鏈表的區別。
單鏈表的尾結點沒有后繼結點(后繼結點為空),頭結點沒有前驅節點,而循環單鏈表尾結點的后繼結點為頭結點(這里指實際頭結點),頭結點的前驅節點為尾結點; 雙鏈表同單鏈表。

6.帶虛擬頭結點的單鏈表和不帶虛擬頭結點的單鏈表的優勢體現在哪里?如何區分頭結點與虛擬頭結點?
和不帶虛擬頭結點的單鏈表相比,帶虛擬頭結點的單鏈表不僅統一了第一個結點及其后繼結點的處理過程,還統一了空表和非空表的處理過程。自己要學會結合語境判斷,題目中說的頭結點是虛擬頭結點還是實際的頭結點。
[203. 移除鏈表元素]
https://leetcode-cn.com/problems/remove-linked-list-elements/

7.對單鏈表,哪邊是頭,哪邊是尾?插入時,(A)與(B)能否交換,為什么?
q = ListNode(13)
q.next = head.next ---- (A)
head.next = q ---- (B)
(注意:這里由於有時候會有人弄不清楚頭結點與虛擬頭結點的區別,所以經常會取head這樣**的名字,考生自己要清楚,別被帶到溝里去了)
對於單鏈表,最前面的元素就是頭結點(如果這個元素在之后不被替代),最后的元素就是尾結點。(A)與(B)不能交換,若兩者交換,head.next已經更新為q, q就無法定位到原來頭結點所在的位置上了。
[61. 旋轉鏈表]
https://leetcode-cn.com/problems/rotate-list/

8.敘述棧頂指針, (虛擬)隊頭指針,隊尾指針的概念。
注意:為保證隊列元素操作的一致性,類似於虛擬頭指針的概念,建立虛擬隊尾指針,指向隊尾元素的下一個元素
棧頂指針指向棧最頂部的元素,隊頭指針指向隊列中先插入的元素,隊尾指針指向最后一個插入元素的后面一個元素。

9.“秋江楚雁宿沙洲,雁宿沙洲淺水流。流水淺洲沙宿雁,洲沙宿雁楚江秋。”請使用棧的基本操作來判斷一個單詞是否為回文單詞。(只允許使用一個棧)
[劍指 Offer II 018. 有效的回文]
https://leetcode-cn.com/problems/XltzEq/
[234. 回文鏈表]
https://leetcode-cn.com/problems/palindrome-linked-list/
字符串中每個字符逐一入棧,逐一出棧,與原字符串比較

  1. 簡述如何檢驗括號有效性。
    [20. 有效的括號]
    https://leetcode-cn.com/problems/valid-parentheses/
    遇見‘(’則將‘)’入棧,遇見‘)’將棧頂元素與之比較。

  2. 在玩游戲的時候,一般會標記重生點,角色快死了可以回到重生點復活繼續游戲,請從數據結構角度簡單分析其基本原理。
    重生點用棧存儲了玩家在到達重生點時的信息,復活時,將這些信息出棧覆蓋瀕死玩家的數據信息。

12.如何解決隊列假溢出問題?如何在循環隊列中區分隊空與隊滿?
[622. 設計循環隊列]
https://leetcode-cn.com/problems/design-circular-queue/
解決隊列假溢出的方法有兩種,一種是只用一個隊尾指針,將元素始終存儲在0-(隊尾指針-1)的范圍之內;另外一種是建立循環隊列。在循環隊列中,區分隊空與堆滿也有兩種方法,一種是在結構體中加入tag進行標識,另外一種是預留出一個空位,具體操作是,K個元素,存儲在0-K-1這K個位置當中,設置隊列長度為K+1,當rear==head時為隊空,當(head-rear)%(K+1) == 1時為隊滿。(head-rear)%(K+1)的值的變化:0, K,K-1,...2,[1]

  1. 請分別使用循環順序隊列的基本操作和遞歸來計算某個月的斐波那契的兔子總數。兩種做法在時間復雜度與空間復雜度上有什么不同?這樣的做法在n>=47時應當注意什么?
    [劍指 Offer 10- I. 斐波那契數列]
    https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/comments/
    [斐波那契數列兩種算法的時間復雜度]
    https://www.cnblogs.com/abyss1114/p/7272657.html
    時間復雜度上,遞歸的方法為2的n次冪,非遞歸為n,空間復雜度上,遞歸為n,非遞歸為1, 當n>=47時,最好在每一步除以一個極限數,防止結果超出整數int的數據范圍。

14.如何用遞歸解決漢諾塔問題?如何解釋程序的運行過程?
[面試題 08.06. 漢諾塔問題]
https://leetcode-cn.com/problems/hanota-lcci/
先把1: A->B,再n-1:A->C, 1:B->C

  1. 如何用棧實現隊列,又如何用隊列實現棧(角色互換法)?基於此,請說說你是如何認識棧與隊列的時間本質的?
    兩個棧,一個入,一個出,出的空找入要,倒兩下,正過來了
    兩個隊列,強行實現,注意交換身份
    棧是時間的倒放,隊列是時間的順序執行

  2. 簡單字符串匹配算法的劣勢體現在哪兒?如何改進?改進后的kmp算法的next數組是如何求的?求出next數組后又怎么辦?如何求next數組!!!!
    因為 KMP 利用已匹配部分中相同的「前綴」和「后綴」來加速下一次的匹配。
    因為 KMP 的原串指針不會進行回溯(沒有朴素匹配中回到下一個「發起點」的過程)。

第一點很直觀,也很好理解。
我們可以把重點放在第二點上,原串不回溯至「發起點」意味着什么?
其實是意味着:隨着匹配過程的進行,原串指針的不斷右移,我們本質上是在不斷地在否決一些「不可能」的方案。
當我們的原串指針從 i 位置后移到 j 位置,不僅僅代表着「原串」下標范圍為 [i,j)[i,j) 的字符與「匹配串」匹配或者不匹配,更是在否決那些以「原串」下標范圍為 [i,j)[i,j) 為「匹配發起點」的子集。
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

KMP個人感悟:就像打游戲,打的贏就打,打不贏就跑,免得每次打死了要回原地復活

[28. 實現 strStr()]
https://leetcode-cn.com/problems/implement-strstr/
參考題解:
https://leetcode-cn.com/problems/implement-strstr/solution/shua-chuan-lc-shuang-bai-po-su-jie-fa-km-tb86/

子串為aaabab, 求next數組 012010

17.在用數組存儲矩陣的時候,如何避免元素重復存儲(對稱矩陣->三角矩陣),如何處理零元素大量規律存在(三角矩陣),以及大量不規律存在(稀疏矩陣(三元組表法,十字鏈表法))的問題?
利用公式來將二維數組壓縮到一維的層面上去,大量不規則存在的矩陣,可采用三元組表法,十字鏈表法存儲之。

18.應當如何定義葉子結點?由此看出樹與圖具有怎樣的關系?
(結點的度,葉子結點,分支結點,樹的度)
結點的度為0的結點就是葉子結點,其中,結點的度是指樹中結點的出度,葉子結點即結點的度為0的結點,分支結點即結點的度不為0的結點,樹的度是指樹內所有結點度的最大值。
由此看出,樹不過是一種特殊的圖結構,適用於圖的方法,一樣適用於樹(如DFS,BFS)

19.如何用非技術人員也能聽懂的語言描述樹的結構?(聯系家系圖)
(孩子結點,雙親結點,兄弟結點,祖先結點,子孫結點,結點的層次(類似輩分),堂兄弟結點(有病吧),樹的深度,有序樹,無序樹)
自己腦子里想一下

20.如何用樹的性質進行數學運算?(難/麻煩)
(1)樹的結點數目=所有結點的度的總和+1
(2)度為k的樹第i層最多有k的(i-1)次方個結點
(3)深度為h的k叉樹最多有(k的h次方-1)/k-1
(4)具有n個結點的k叉樹的最小深度為logk[n(k-1)+1]取整

21.請先回答問題先序遍歷之先是什么先?先序遍歷,后序遍歷,層次遍歷與前序遍歷,中序遍歷,后序遍歷,層次遍歷的關系是什么?再寫出下面這個樹的先序遍歷,后序遍歷,層次遍歷的節點順序。(不要背,遞歸看即可)
先序遍歷先的是樹根,先序遍歷,后序遍歷,層次遍歷指的是樹的遍歷,前序遍歷,中序遍歷,后序遍歷,層次遍歷指的是二叉樹的遍歷,

image

先序遍歷:A B E K L F C G D H M I J
后序遍歷:K L E F B G C M H I J D A
層次遍歷:A B C D E F G H I J K L M
樹的定義與樹的遍歷可以說是完全統一在遞歸之下的。

22.簡述樹與二叉樹的區別
戀拽FHB 2017-04-24 23:22樹可以為空,叫空樹(嚴蔚敏《數據結構(C語言版)》第118頁明確定義:樹是n(n>=0)個結點的有限集)。他們之間的差別主要在於實現方式的不同。二叉樹是二叉鏈表(有左右子樹的指針),樹通常是兄弟孩子鏈表(有孩子指針,兄弟指針,兩個指針)。二叉樹區分左右,非有序樹不區分左右。

23.滿二叉樹與完全二叉樹的區別是什么?(滿二叉樹是完全二叉樹的一種特例)
滿二叉樹最下面一層排滿,完全二叉樹只要沒有不排滿的就行。

24.試證明:對任何非空二叉樹 T,若其葉結點個數為 n0,度數為 2 的結點個數為 n2,則n0 = n2 + 1
結點數 = n0 + n1 + n2 = 所有結點的度數 + 1 = n1 + 2*n2 + 1
n0 = n2 + 1

25.試比較二叉樹的順序存儲與鏈式存儲,說明其在不同應用場景下的優缺點
二叉樹順序存儲操作簡單,但增刪難度大,且對非完全二叉樹而言,比較浪費空間。

26.請先回答問題前序遍歷之前是什么前?再寫出下面這個樹的前序遍歷,中序遍歷,后序遍歷,層次遍歷的節點順序。(不要背,遞歸看即可)
image

前序遍歷之前是樹根在前,
前序遍歷:ABCDEFGHK
中序遍歷:BDCAEHGKF
后序遍歷:DCBHKGFEA
層次遍歷:ABECFDGHK

27.請用python寫出二叉樹的先序遍歷,中序遍歷,后序遍歷的遞歸算法。
[144. 二叉樹的前序遍歷]
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/submissions/

點擊查看代碼
def preorder(self,root:TreeNode):
        if(root==None):
            return
        self.ls.append(root.val)
        self.preorder(root.left)
        self.preorder(root.right)

[94. 二叉樹的中序遍歷]
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

點擊查看代碼
def inorder(self,root:TreeNode):
	if(root==None):
    	return
    self.inorder(root.left)
    self.ls.append(root.val)
    self.inorder(root.right)

[145. 二叉樹的后序遍歷]
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

點擊查看代碼
def postorder(self,root:TreeNode):
        if(root==None):
            return
        self.postorder(root.left)
        self.postorder(root.right)
        self.ls.append(root.val)

28.(必考&&重要2)請用python寫出二叉樹的先序遍歷,中序遍歷,后序遍歷(SL),層次遍歷的非遞歸算法。
[144. 二叉樹的前序遍歷]
https://leetcode-cn.com/problems/binary-tree-preorder-traversal/submissions/

點擊查看代碼
def preorderTraversal(self, root: TreeNode) -> List[int]:
        res, stack = [], []
        node = root
        while(stack or node):
            while(node):
                res.append(node.val)
                stack.append(node)
                node = node.left
            node = stack[-1]
            stack.pop()
            node = node.right
        return res

[94. 二叉樹的中序遍歷]
https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

點擊查看代碼
def inorderTraversal(self, root: TreeNode) -> List[int]:
        res, stack = [], []
        node = root
        while(stack or node):
            while(node):
                stack.append(node)
                node = node.left
            node = stack[-1]
            stack.pop()
            res.append(node.val)
            node = node.right
        return res

[145. 二叉樹的后序遍歷](SL)
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/

點擊查看代碼
def postorderTraversal(self, root: TreeNode) -> List[int]:
        res, stack = [], []
        node, p = root, None
        while(stack or node):
            while(node):
                stack.append(node)
                node = node.left
            node = stack[-1]
            if(node.right==None or node.right==p):
                res.append(node.val)
                stack.pop()
                p = node
                node = None
            else:
                node = node.right
        return res

[102. 二叉樹的層序遍歷]
https://leetcode-cn.com/problems/binary-tree-level-order-traversal/

點擊查看代碼
def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res, queue = [], []
        if(root==None):
            return res
        queue.append(root)
        while(queue):
            ans = []
            sz = len(queue)
            while(sz>0):
                t = queue[0]
                ans.append(t.val)
                if(t.left):
                    queue.append(t.left)
                if(t.right):
                    queue.append(t.right)
                queue.pop(0)
                sz = sz-1
            res.append(ans)
        return res

29.請用python寫出N叉樹的先序遍歷,后序遍歷,層次遍歷算法。

30.能否由先根遍歷與中根遍歷唯一的確定一棵樹?試說明其確定過程,后根遍歷與中根遍歷呢?先根遍歷與后根遍歷呢?如果不能請舉出反例。能否說后根遍歷是先根遍歷的倒序?
image

31.對一棵二叉樹進行遍歷時,我們以二叉鏈表作為存儲結構,此時只能找到除根結點以外的任一結點的左、右孩子,而不能直接訪問結點在遍歷時所得的序列中的先驅和后繼信息。如何解決這一問題呢?
[線索化的實質是當二叉樹中某一結點不存在左孩子或右孩子時,將其LeftChild域或RightChild域中存入該結點的直接先驅或直接后繼。通常我們在遍歷二叉樹時才能實現對其線索化。]

32.如何利用棧實現表達式的運算?
[劍指 Offer II 036. 后綴表達式]
https://leetcode-cn.com/problems/8Zf90G/

33.請簡要說明樹,二叉樹,森林之間的轉換過程

34.哈夫曼樹的每個葉子結點的路徑為什么是唯一的?如何計算哈夫曼樹的路徑長度?如何構建最優哈夫曼樹?
https://baike.baidu.com/item/哈夫曼樹/2305769?fr=aladdin
https://haokan.baidu.com/v?pd=wisenatural&vid=7342058971484704343
因為樹的葉子結點的入讀均為1,出度為0,所以路徑就唯一確定

35.請列出下圖的深度優先搜索與廣度優先搜索的正確順序,如何更好的記錄已訪問結點?
image

深度優先搜索:01374256
廣度優先搜索:01234567

36.請簡單回憶kruskal,prim,Dijkstra,flyord算法,AOV網與AOE網。
Kruskal:
image

按權值由小到大取每一條邊,若構成回路就舍棄。

Prim:
image

用到已知集合最近的點更新未知集合每一個點的距離數組

Dijkstra:
image

用到源點距離最近的點更新未知集合每一個點的距離數組

Flyord
image

37.簡述順序查找中監察哨的作用。
防止比較時數組下標超出邊界,同時充當臨時變量的作用

38.二叉查找樹中,若待刪除的結點既有左子樹,也有右子樹,應當如何處理?
用二叉查找樹中序遍歷的前一個結點/后一個結點來交換之,再刪除交換的結點

39.請列舉兩種構造哈希表的常用方法。
開放尋址法與拉鏈法

40.怎樣的排序算法是穩定的排序算法?哪些排序算法是穩定的?哪些不是?
如果待排序的記錄序列中存在多個排序碼相同的記錄,經過排序后,這些具有相同排序碼的記錄之間的相對次序保持不變,則我們認為該排序方法是穩定的;若具有相同排序碼的記錄之間的相對次序發生了變化,則認為該排序方法是不穩定的。
插入排序,冒泡排序與歸並排序穩定,其余均不穩定(學過的排序算法中)

41.3)插入排序用移動法還是交換法?(要是非要你填移動法的代碼怎么辦?)
移動法,本質還是移動法
image

42.請問二分插入排序的時間復雜度是多少?學過的算法里面,有哪些平均時間復雜度不是O(n^2)? 哪些最壞時間復雜度不是O(n^2)?哪些排序是穩定的?(插入,冒泡與歸並)
二分插入排序的時間復雜度仍然是O(n2)的,快排,歸並,堆排序,希爾排序不是O(n2),其余均是O(n2), 插入冒泡與歸並是穩定的

43.如何實現堆排序算法?
image
image

大的講,先構造堆,再逐一縮小堆的規模,小的講,子節點選大的交換


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM