日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

b+树时间复杂度_数据结构:线性表,栈,队列,数组,字符串,树和二叉树,哈希表...

發布時間:2025/3/11 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 b+树时间复杂度_数据结构:线性表,栈,队列,数组,字符串,树和二叉树,哈希表... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:張人大


代碼效率優化

復雜度 -- 一個關于輸入數據量n的函數

  • 時間復雜度 -- 昂貴
  • 與代碼的結構設計有著緊密關系
  • 一個順序結構的代碼,時間復雜度是O(1), 即任務與算例個數 n 無關
  • 空間復雜度 -- 廉價
  • 與數據結構設計有關

數據結構 -- 考慮如何去組織計算機中一定量的數據。

數據結構連接時空,用空間換取時間。

數據處理 -- 了解問題,明確數據操作方法,設計出更加高效的數據結構類型

  • 找到需要處理的數據,計算結果,再把結果保存下來
  • 把結果存到新的內存空間中
  • 把結果存到已使用的內存空間中
  • 基本操作只有三個:增,刪,查
  • 增和刪可以細分為數據結構的中間以及最后的增和刪
  • 查找可以細分為按照位置條件查找和數據數值特征查找
  • 所有數據處理都是這些基本操著的組合和疊加
  • 只有字典類型數據結構能在 O(1) 的時間復雜度內完成查找動作
  • 回歸問題本源,明確數據被處理的動作,來解決數據結構的問題

想了解更多,歡迎關注我的微信公眾號:Renda_Zhang


線性表

n 個具有相同特性的元素的有限序列,Linear List

數據元素之間的關系是一對一的關系

  • 即除了頭尾元素外,其它數據元素都是首尾相接的
  • 這句話只適用大部分線性表,而不是全部
  • 比如,循環鏈表尾的指針指向首位結點

實現方式

  • 最常用的是鏈式表達,也叫線性鏈表或鏈表
  • 每個結點包括具體的數據值和指向下一個結點的指針
  • 單向鏈表,循環鏈表,雙向鏈表,雙向循環鏈表
  • 新增和刪除為 O(1) 時間復雜度,而查找為 O(n)
  • 適合數據元素個數不確定,且經常進行新增和刪除
  • 鏈表的翻轉,快慢指針的方法,是必須掌握的內容
  • 使用數組實現,也叫順序存儲,順序表

類別

  • 一般線性表,可以自由的刪除和添加結點
  • 受限線性表,主要包含棧和隊列

棧和隊列是特殊的線性表,本質上他們都可以被看作是一類基本結構

線性表案例

  • 鏈表的翻轉
  • 快慢指針
  • 查找奇數個數的鏈表的中間位置結點的數值
  • 判斷鏈表是否有環

后進先出的(限制后的)線性表,Last In First Out, Stack.

新增和刪除操作只能在這個線性表的表尾進行,即在線性表基礎上加了限制

  • 新增: 壓棧 push, which adds an element to the collection
  • 刪除: 出棧 pop, which removes the most recently added element

功能上,數組或者鏈表可以代替棧,但它們靈活性過高,數據量大時有風險

棧頂和棧底是用來表示這個棧的兩個指針

  • 棧頂 (top) 是表尾,用來輸入數據
  • 棧底 (bottom) 是表頭

棧有順序表示和鏈式表示,分別稱作順序棧和鏈棧

  • 順序棧
  • 可以借助數組來實現
  • 數組的首元素存在棧底,尾元素放在棧頂
  • 定義指針 top 來指示棧頂元素在數組的位置
  • 棧中只有一個元素,則 top = 0
  • 以 top 是否為 -1 來判定是否為空棧
  • 棧頂 top 需小于棧的最大容量
  • 出棧操作,只需要 top - 1 即可
  • 鏈式棧
  • 用鏈表的方式實現
  • 通常把棧頂放在單鏈表的頭部
  • top 指針替換了鏈表原來的尾指針,去掉了頭指針
  • 出棧操作,將 top 指針指向棧頂元素的 next 指針即可
  • 對比棧和一般線性表
  • 相同點:
  • 操作原理相似
  • 時間復雜度一樣
  • 都依賴當前位置指針進行數據對象的操作
  • 區別:棧只能新增和刪除棧頂的數據結點

棧的案例

  • 判斷括號字符串是否合法
  • 瀏覽器頁面訪問的后退和前進

隊列

先進先出 (限制后的) 線性表, First In First Out, Queue

新增和刪除操作只能分別在隊尾和隊頭進行

  • 先進 - 隊列的數據新增操作只能在末端進行, add
  • 不允許在隊列的中間某個結點后新增數據
  • 先出 - 隊列的數據刪除操作只能在始端進行, remove
  • 不允許在隊列的中間某個結點后刪除數據

隊列適合面對數據處理順序非常敏感的問題

  • 可以確定隊列長度最大值, 建議使用循環隊列
  • 無法確定隊列長度時, 應考慮使用鏈式隊列

front 和 rear 兩個指針

  • 隊頭 (front), 用來刪除數據
  • 隊尾 (rear), 用來增加數據

隊列有兩種存儲方式, 即順序隊列和鏈式隊列

  • 順序隊列
  • 依賴數組來實現
  • 數據在內存中也是順序存儲
  • 進行新增插入操作時,
  • 尾指針會向后移動
  • 時間復雜度為 O(1)
  • 如果只刪除頭的第一個元素時
  • 每次刪除都需要把整個數組前移
  • 時間復雜度為 O(n)
  • 使用循環隊列
  • 必須有一個固定的長度
  • 實現刪除的時間復雜度為 O(1)
  • 使用 flag 來判斷隊列空或滿
  • 鏈式隊列
  • 依賴鏈表來實現
  • 數據依賴每個結點的指針互聯
  • 是離散存儲線性結構
  • 實際上就是尾進頭出的單鏈線性表
  • 在空間上更為靈活
  • 通常會增加一個頭結點
  • 讓 front 指針指向頭結點
  • 頭結點不存儲數據, 只是輔助標識
  • 當進行數據刪除時, 實際刪除的是頭結點的后繼結點
  • 隊列為空時, 頭尾指針都指向頭結點
  • 對比隊列和一般線性表
  • 隊列繼承了線性表的優點和不足
  • 是加了限制的線性表

隊列案例

  • 約瑟夫環 - Josephus problem

數組

數組可以看成是線性表的一種推廣,它屬于另外一種基本的數據結構

數組是數據結構中的最基本結構

  • 幾乎所有的程序設計語言都把數組類型設定為固定的基礎變量類型。
  • 可以把數組理解為一種容器,它可以用來存放若干個相同類型的數據元素。
  • 例如:
  • 存放的數據是整數型的數組,稱作整型數組;
  • 存放的數據是字符型的數組,則稱作字符數組;
  • 另外還有一類數組比較特殊,它是數組的數組,也可以叫作二維數組。
  • 可以把普通的數組看成是一個向量,那么二維數組就是一個矩陣。
  • 數組在內存中是連續存放的,數組內的數據,可以通過索引值直接取出得到。

數組的索引就是對應數組空間

  • 在進行新增、刪除、查詢操作的時候,完全可以根據代表數組空間位置的索引值進行。
  • 只要記錄該數組頭部的第一個數據位置,然后累加空間位置即可。

數組的基本操作

具有增刪困難、查找容易的特點,可以在任意位置增刪數據,所以數組的增刪操作會更為多樣。

  • 新增操作
  • 若插入數據在最后,則時間復雜度為 O(1)
  • 如果中間某處插入數據,則時間復雜度為 O(n)
  • 刪除操作
  • 在數組的最后刪除一個數據元素,則時間復雜度是 O(1)
  • 在這個數組的中間某個位置刪除一條數據, 時間復雜度為 O(n)
  • 查找操作
  • 如果只需根據索引值進行一次查找,時間復雜度是 O(1)
  • 要在數組中查找一個數值滿足指定條件的數據,則時間復雜度是 O(n)。

對比數組和鏈表

  • 鏈表的長度是可變的,數組的長度是固定的,在申請數組的長度時就已經在內存中開辟了若干個空間。如果沒有引用 ArrayList 時,數組申請的空間永遠是我們在估計了數據的大小后才執行,所以在后期維護中也相當麻煩。
  • 鏈表不會根據有序位置存儲,進行插入數據元素時,可以用指針來充分利用內存空間。數組是有序存儲的,如果想充分利用內存的空間就只能選擇順序存儲,而且需要在不取數據、不刪除數據的情況下才能實現。

數組的案例

  • 基于數組,計算平均值

字符串

由 n 個字符組成的一個有序整體( n >= 0 )

對比字符串和線性表

  • 字符串的邏輯結構和線性表極為相似,區別僅在于串的數據對象約束為字符集。
  • 字符串的基本操作和線性表有很大差別:
  • 在線性表的基本操作中,大多以“單個元素”作為操作對象;
  • 在字符串的基本操作中,通常以“串的整體”作為操作對象;
  • 字符串的增刪操作和數組很像,復雜度也與之一樣。但字符串的查找操作就復雜多了,它是參加面試、筆試常常被考察的內容。

特殊的字符串

  • 空串,指含有零個字符的串。例如,s = "",書面中也可以直接用 ? 表示。
  • 空格串,只包含空格的串。它和空串是不一樣的,空格串中是有內容的,只不過包含的是空格,且空格串中可以包含多個空格。例如,s = " ",就是包含了 3 個空格的字符串。
  • 子串,串中任意連續字符組成的字符串叫作該串的子串。
  • 原串通常也稱為主串。

字符串的存儲結構與線性表相同,也有順序存儲和鏈式存儲兩種

  • 字符串的順序存儲結構,是用一組地址連續的存儲單元來存儲串中的字符序列,一般是用定長數組來實現。有些語言會在串值后面加一個不計入串長度的結束標記符,比如 0 來表示串值的終結。
  • 字符串的鏈式存儲結構,與線性表是相似的,但由于串結構的特殊性(結構中的每個元素數據都是一個字符),如果也簡單地將每個鏈結點存儲為一個字符,就會造成很大的空間浪費。因此,一個結點可以考慮存放多個字符,如果最后一個結點未被占滿時,可以使用 "#" 或其他非串值字符補全。
  • 每個結點設置字符數量的多少,與串的長度、可以占用的存儲空間以及程序實現的功能相關。
  • 除了在連接串與串操作時有一定的方便之外,不如順序存儲靈活,在性能方面也不如順序存儲結構好。

字符串的基本操作

  • 新增操作
  • 和數組非常相似,都牽涉對插入字符串之后字符的挪移操作,所以時間復雜度是 O(n)。
  • 對于特殊的插入操作時間復雜度也可以降低為 O(1)。例如,在 s1 的最后插入 s2,也叫作字符串的連接。
  • 刪除操作
  • 和數組同樣非常相似,也可能會牽涉刪除字符串后字符的挪移操作,所以時間復雜度是 O(n)。
  • 對于特殊的刪除操作時間復雜度也可以降低為 O(1)。例如,在 s1 的最后刪除若干個字符,不牽涉任何字符的挪移。
  • 查找操作
  • 子串查找(字符串匹配)
  • 在字符串 A 中查找字符串 B,則 A 就是主串,B 就是模式串。
  • 主串的長度記為 n,模式串長度記為 m,則n>m。
  • 字符串匹配算法的時間復雜度就是 n 和 m 的函數。

字符串匹配算法的案例

  • 查找出兩個字符串的最大公共字串

樹和二叉樹

樹 -- Tree

  • 樹結構在存在“一對多”的數據關系中,可被高頻使用,這也是它區別于鏈表系列數據結構的關鍵點。
  • 樹是由結點和邊組成的,不存在環的一種數據結構。
  • 樹滿足遞歸定義的特性。如果一個數據結構是樹結構,那么剔除掉根結點后,得到的若干個子結構也是樹,通常稱作子樹。
  • 樹的結點的層次從根結點算起,根為第一層,根的“孩子”為第二層,根的“孩子”的“孩子”為第三層,依此類推。
  • 樹中結點的最大層次數,就是這棵樹的樹深(稱為深度,也稱為高度)。

二叉樹 -- Binary Tree

二叉樹每個結點最多有兩個子結點,分別稱作左子結點和右子結點。

二叉樹中兩個特殊的類型

  • 滿二叉樹,定義為除了葉子結點外,所有結點都有 2 個子結點。
  • 完全二叉樹,定義為除了最后一層以外,其他層的結點個數都達到最大,并且最后一層的葉子結點都靠左排列。它方便了順序存儲法的存儲方式。

存儲二叉樹的兩種辦法

  • 鏈式存儲法,也就是像鏈表一樣,每個結點有三個字段,一個存儲數據,另外兩個分別存放指向左右子結點的指針。
  • 順序存儲法,就是按照規律把結點存放在數組里。如圖所示。

樹的基本操作

遍歷

  • 前序遍歷,對樹中的任意結點來說,先打印這個結點,然后前序遍歷它的左子樹,最后前序遍歷它的右子樹。 public static void preOrderTraverse(Node node) { if (node == null) return; System.out.print(node.data + " "); preOrderTraverse(node.left); preOrderTraverse(node.right); }
  • 中序遍歷,對樹中的任意結點來說,先中序遍歷它的左子樹,然后打印這個結點,最后中序遍歷它的右子樹。 public static void inOrderTraverse(Node node) { if (node == null) return; inOrderTraverse(node.left); System.out.print(node.data + " "); inOrderTraverse(node.right); }
  • 后序遍歷,對樹中的任意結點來說,先后序遍歷它的左子樹,然后后序遍歷它的右子樹,最后打印它本身。 public static void postOrderTraverse(Node node) { if (node == null) return; postOrderTraverse(node.left); postOrderTraverse(node.right); System.out.print(node.data + " "); }

二叉樹的增刪查操作很普通,時間復雜度與鏈表并沒有太多差別

二叉查找樹 -- Binary Search Tree, BST

特性

  • 在二叉查找樹中的任意一個結點,其左子樹中的每個結點的值,都要小于這個結點的值。
  • 在二叉查找樹中的任意一個結點,其右子樹中每個結點的值,都要大于這個結點的值。
  • 在二叉查找樹中,會盡可能規避兩個結點數值相等的情況。
  • 對二叉查找樹進行中序遍歷,就可以輸出一個從小到大的有序數據隊列。

查找操作 -- 利用了“二分查找”,所消耗的時間復雜度為 O(logn)。

  • 首先判斷根結點是否等于要查找的數據,如果是就返回。
  • 如果根結點大于要查找的數據,就在左子樹中遞歸執行查找動作,直到葉子結點。
  • 如果根結點小于要查找的數據,就在右子樹中遞歸執行查找動作,直到葉子結點。

插入操作

  • 插入操作很簡單。從根結點開始,如果要插入的數據比根結點的數據大,且根結點的右子結點不為空,則在根結點的右子樹中繼續嘗試執行插入操作。直到找到為空的子結點執行插入動作。
  • 二叉查找樹插入數據的時間復雜度是 O(logn)。這里的時間復雜度更多是消耗在了遍歷數據去找到查找位置上,真正執行插入動作的時間復雜度仍然是 O(1)。

刪除操作

  • 情況一,如果要刪除的結點是某個葉子結點,則直接刪除,將其父結點指針指向 null 即可。
  • 情況二,如果要刪除的結點只有一個子結點,只需要將其父結點指向的子結點的指針換成其子結點的指針即可。
  • 情況三,如果要刪除的結點有兩個子結點,則有兩種可行的操作方式:
  • 第一種,找到這個結點的左子樹中最大的結點,替換要刪除的結點。
  • 第二種,找到這個結點的右子樹中最小的結點,替換要刪除的結點。

樹的案例

字典樹 -- Dictionary Tree

  • 第一,根結點不包含字符;
  • 第二,除根結點外每一個結點都只包含一個字符;
  • 第三,從根結點到某一葉子結點,路徑上經過的字符連接起來,即為集合中的某個字符串。

哈希表

哈希表 -- Hash Table, 也叫作散列表。

哈希表是一種特殊的數據結構,它與數組、鏈表以及樹等我們之前學過的數據結構相比,有很明顯的區別。

  • 線性表中的棧和隊列對增刪有嚴格要求,它們會更關注數據的順序。
  • 數組和字符串需要保持數據類型的統一,并且在基于索引的查找上會更有優勢。
  • 樹的優勢則體現在數據的層次結構上。
  • 哈希表優勢體現在,無論有多少數據,查找、插入、刪除只需要接近常量的時間,即 O(1)的時間級。

核心思想

實現 “地址 = f (關鍵字)” 的映射關系,快速完成基于數據的數值的查找。

哈希函數的設計

直接定制法

哈希函數為關鍵字到地址的線性函數。如,H (key) = a*key + b。 這里,a 和 b 是設置好的常數。

數字分析法

假設關鍵字集合中的每個關鍵字 key 都是由 s 位數字組成(k1,k2,…,Ks),并從中提取分布均勻的若干位組成哈希地址。

平方取中法

如果關鍵字的每一位都有某些數字重復出現,并且頻率很高,我們就可以先求關鍵字的平方值,通過平方擴大差異,然后取中間幾位作為最終存儲地址。

折疊法

如果關鍵字的位數很多,可以將關鍵字分割為幾個等長的部分,取它們的疊加和的值(舍去進位)作為哈希地址。

除留余數法

預先設置一個數 p,然后對關鍵字進行取余運算。即地址為 key mod p。

解決哈希沖突

開放定址法

常用的探測方法是線性探測法。比如有一組關鍵字 {34,35,36,45},采用的哈希函數為 key mod 11。當插入 34,35,36 時可以直接插入,地址分別為 1、2、3。而當插入 45 時,哈希地址為 45 mod 11 = 1。然而,地址 1 已經被占用,因此沿著地址 1 依次往下探測,直到探測到地址 4,發現為空,則將 45 插入其中。

鏈地址法

將哈希地址相同的記錄存儲在一張線性鏈表中。如果出現沖突,就在對應的位置上加上鏈表的數據結構。

哈希表的基本操作

哈希表中的增加和刪除數據操作,不涉及增刪后對數據的挪移問題

  • 如果是采用數組實現就需要考慮數據的挪移問題

哈希表查找的細節過程是:對于給定的 key,通過哈希函數計算哈希地址 H (key)。

  • 如果哈希地址對應的值為空,則查找不成功。
  • 反之,則查找成功。

哈希表的案例

實時返回用戶的字符串搜索結果


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的b+树时间复杂度_数据结构:线性表,栈,队列,数组,字符串,树和二叉树,哈希表...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。