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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

十二、二叉树

發布時間:2025/3/19 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 十二、二叉树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大綱:

  • 樹、二叉樹
  • 二叉查找樹
  • 平衡二叉查找樹、紅黑樹
  • 遞歸樹

一、樹(Tree)

1、樹的相關概念

(1)節點

其中,每個元素稱為“節點”;用來連接相鄰節點之間的關系,成為“父子關系”。其他概念:“父節點、子節點、兄弟節點,根節點,葉子節點或葉節點”
==》A 節點就是 B 節點的父節點,B 節點是 A 節點的子節點。B、C、D 這三個節點的父節點是同一個節點,所以它們之間互稱為兄弟節點。我們把沒有父節點的節點叫作根節點,也就是圖中的節點 E。我們把沒有子節點的節點叫作葉子節點或者葉節點,比如圖中的 G、H、I、J、K、L 都是葉子節點。

(2)高度( Height )、深度( Depth )、層( Level )

不要混淆!

  • 節點的高度 = 節點到葉子節點的最長路徑(邊數)
  • 節點的深度 = 根節點到該節點所經歷的邊的個數
  • 節點的層數 = 節點的深度 + 1
  • 樹的高度 = 根節點的 高度

示例:

二、二叉樹(Binary Tree)

最常用 的樹結構

1、相關概念

(1)二叉樹

二叉樹:每個節點最多有兩個叉,也就是兩個子節點(左子結點、右子節點)。二叉樹并不要求每個節點都有兩個子節點,有的節點可以只有一個左子結點(或右子節點),有的節點沒有子節點。

(2)滿二叉樹

特點:葉子節點全都在最底層,除葉子節點外,每個結點都有左右兩個子節點。

(3)完全二叉樹

完全二叉樹:葉子節點都在最底下兩層,最后一層的葉子節點都靠左排列,并且除了最后一層,其他層的節點個數都要達到最大。

注意區分:

2、二叉樹的表示(存儲)

兩種存儲方法:
①基于指針或引用的二叉鏈式存儲法
②基于數組的順序存儲方法。

(1)鏈式存儲法——常用

每個節點有三個字段,分別存儲:數據、指向左右子節點的指針。
==》只要通過根節點,就可以通過左右節點的指針,將整棵樹串起來。

(2)順序存儲法

一般情況下,為了方便計算子節點,根節點會存儲在下標為 1 的位置。

  • 將根節點存儲在下標 i = 1 的位置,其左節點存儲在下標 2 * i = 2 的位置,右子節點存儲在 2 * i + 1 = 3的位置。
  • 依次類推:
    • 若結點 X 存儲在數組中下標為 i 的位置,
    • 其左節點下標: 2 * i
    • 其右節點下標: 2 * i + 1
    • 其父節點下標:i / 2

(3)分析

若二叉樹為完全二叉樹,則數組存儲是最節省內存的一種方式(不需要存儲額外的左右子節點的指針)
==》堆——本質:完全二叉樹,最常用的存儲方式就是數組。

3、二叉樹遍歷

(1)方法

三種方法:前序遍歷、中序遍歷、后序遍歷
==》節點與它的左右子樹節點遍歷的先后順序:中代表該節點,左代表其左子樹,右代表其右子樹。

  • 前序遍歷:中、左、右
  • 中序遍歷:左、中、右
  • 后序遍歷:左、右、中

(2)代碼實現

關鍵點:遞歸代碼 《== 遞歸公式

前序遍歷的遞推公式: preOrder(r) = print r->preOrder(r->left)->preOrder(r->right)中序遍歷的遞推公式: inOrder(r) = inOrder(r->left)->print r->inOrder(r->right)后序遍歷的遞推公式: postOrder(r) = postOrder(r->left)->postOrder(r->right)->print r

遞歸代碼:
==》遍歷時間復雜度:O(n)

// 偽代碼void preOrder(Node * root) {if(root == null)return;print root; // 打印 root 節點preOrder(root->left);preOrder(root->right); }void inOrder(Node * root) {if(root == null)return;inOrder(root->left);print root; // 打印 root 節點inOrder(root->right); }void postOrder(Node * root) {if(root == null)return;postOrder(root->left);postOrder(root->right);print root; // 打印 root 節點 }

三、二叉查找樹

特點:支持動態數據集合的快速插入、刪除、查找操作。

1、二叉查找樹(Binary Search Tree)

二叉查找樹是二叉樹中最常用的一種類型,也稱二叉搜索樹??梢?strong>快速插入、刪除、查找操作。

結構要求:樹中的任何一個節點,其左子樹的每個節點的值,都要小于該節點的值,而右子樹節點的值都大于這個節點的值。

2、查找操作

目標:查找一個結點
過程:先取根節點,若它等于要查找的數據,則返回;若要查找的數據的值比根節點小,則在左子樹中遞歸查找;若要查找的數據的值比根節點大,則在右子樹中遞歸查找。

public class BinarySearchTree {private Node tree;public Node find(int data){while(p != null){if (data < p.data)p = p.left;else if(data > p.data)p = p.right;elsereturn p;}return null;}public static class Node {private int data;private Node left;private Node right;public Node(int data){this.data = data;}} }

3、插入操作

類似查找操作,新插入的數據一般都在葉子節點上
==》只需要從根節點開始,依次比較要插入的數據和節點的大小關系。

過程:若要插入的數據比節點的數據大,并且節點的右子樹為空,則將新數據直接插入到右子節點的位置;若不為空,則遞歸遍歷右子樹,查找插入位置。同理,若要插入的數據比節點的數據小,并且節點的左子樹為空,則將新數據直接插入到左子節點的位置;若不為空,則遞歸遍歷左子樹,查找插入位置。

public void insert(int data) {if(tree == null){tree = new Node(data);return 0;}Node p = tree;while(p != null){if(data > p.data) {if(p.right == null) {p.right = new Node(data);return;}p = p.right;}else { // data < p.dataif(p.left == null){p.left = new Node(data);return;}p = p.left;}} }

4、刪除操作

針對要刪除節點的子節點個數的不同,分以下三種情況處理。

  • 若要刪除的節點沒有子節點,則只需之間將其父節點中,指向要刪除節點的指針置為null。
  • 若要刪除的節點只有一個子節點(只有左子節點或右子節點),只需要更新父節點中,指向要刪除節點的指針,讓其指向要刪除節點的子節點即可。
  • 若要刪除的節點有兩個子節點。首先,需要找到該節點的右子樹中最小節點,將它替換到要刪除的節點上,然后再刪除這個最小節點(∵最小節點無左子節點)。
public void delete(int data){Node p = tree; // p 指向要刪除的節點,初始化指向根節點Node pp = null; // pp 記錄 p 的父節點// 找到要刪除的節點while (p != null && p.data != data){pp = p;if(data > p.data)p = p.right;elsep = p.left;} if (p == null)return; // 沒有找到// 要刪除的節點有兩個子節點if(p.left != null && p.right != null){// 查找右子樹中最小節點Node minP = p.right;Node minPP = p; // minPP 表示 minP 的父節點while (minP.left != null){minPP = minP;minP = minP.left;}// 將 minP 的數據替換到 p 中p.data = minP.data; // 下面變成刪除 minPp = minP;pp = minPP;}// 刪除節點是葉子節點或者僅有一個節點Node child; // p 的子節點if(p.left != null)child = p.left;else if(p.right != null)child = p.right;elsechild = null;// 刪除的是根節點if(pp == null)tree = child;else if(pp.left == p)pp.left = child;else pp.right = child; }

實際:非常簡單、取巧的方法——單純地將要刪除的節點標記為“已刪除”,但并不真正從樹中將這個節點去掉。
==》雖較浪費內存空間,但刪除操作就變得簡單多了,且并沒有增加插入、查找操作代碼實現的難度。

5、其他操作

還支持快速查找最大節點、最小節點、前驅節點和后繼節點

中序遍歷二叉查找樹
==》輸出:有序的數據序列,時間復雜度為 O(n)
==》也稱:二叉排序樹

四、支持重復數據的二叉查找樹

實際中常在二叉查找樹中存儲的是包含很多字段的對象。并利用某個字段作為鍵值(key)來構建二叉查找樹。對象中的其他字段稱為衛星數據。

1、插入操作

在二叉查找樹中存儲兩個對象鍵值相同的方法:

  • 二叉查找樹中每個節點不僅存儲一個數據
    ==》通過鏈表和支持動態擴容的數組等數據結構,把值相同的數據都存儲在同一個節點上。
  • 每個節點仍存儲一個數據。在查找插入位置的過程中,若遇到一個節點的值與要插入數據的值相同,則將這個要插入的數據放在這個節點的右子樹,即,將新插入的數據當作大于這個節點的值來處理。

2、查找操作

當要查找數據時,若遇到值相同的節點,不停止查找操作,而繼續在右子樹中查找,知直到遇到葉子節點,才停止。
==》可將鍵值等于要查找值得所有節點都找出來。

3、刪除操作

過程:首先找到每個要刪除的節點,然后按照前面的刪除操作方法依次刪除節點。

五、時間復雜度分析

不同的二叉查找樹形態各式各樣
==》影響查找、插入、刪除操作的執行效率

情況一:最糟糕——退化為鏈表(根節點的左右子樹極度不平衡)
==》查找的時間復雜度:O(n)

情況二:最理想——完全二叉樹(或滿二叉樹)
==》插入、刪除和查找的時間復雜度:O(height)
==》求一棵包含n個節點的完全二叉樹的高度?
完全二叉樹的高度小于等于 log2n。


==》需要構建一種不管怎么刪除、插入數據,在任何時候,都能保持任意節點左右子樹都比較平衡的二叉查找樹——平衡二叉查找樹

平衡二叉查找樹的高度接近 logn,所以插入、刪除、查找操作的時間復雜度也比較穩定,是 O(logn)。

六、思考

問題:既然有了這么高效的散列表,使用二叉樹的地方是不是都可以替換成散列表呢?有沒有哪些地方是散列表做不了,必須要用二叉樹來做的呢?

  • 散列表中的數據是無序存儲的,如果要輸出有序的數據,需要先進行排序。而對于二叉查找樹來說,我們只需要中序遍歷,就可以在 O(n) 的時間復雜度內,輸出有序的數據序列。
  • 散列表擴容耗時很多,而且當遇到散列沖突時,性能不穩定,盡管二叉查找樹的性能不穩定,但是在工程中,我們最常用的平衡二叉查找樹的性能非常穩定,時間復雜度穩定在 O(logn)。
  • 籠統地來說,盡管散列表的查找等操作的時間復雜度是常量級的,但因為哈希沖突的存在,這個常量不一定比 logn 小,所以實際的查找速度可能不一定比 O(logn) 快。加上哈希函數的耗時,也不一定就比平衡二叉查找樹的效率高。
  • 散列表的構造比二叉查找樹要復雜,需要考慮的東西很多。比如散列函數的設計、沖突解決辦法、擴容、縮容等。平衡二叉查找樹只需要考慮平衡性這一個問題,而且這個問題的解決方案比較成熟、固定。
  • 為了避免過多的散列沖突,散列表裝載因子不能太大,特別是是基于開放尋址法解決沖突的散列表,不然會浪費一定的存儲空間。

總結

以上是生活随笔為你收集整理的十二、二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 免费无码毛片一区二区app | 亚洲一线av | 在线观看xxxx| 天堂综合网久久 | 成人av影院 | 黄色欧美一级片 | 久久特黄 | 国产欧美a | 欧美日韩1区2区3区 亚洲日本精品视频 | 外国毛片 | av天天色| 性xxxx18| 欧美aa级 | 久久99久久久久 | 亚洲免费av网站 | 波多野结衣精品在线 | 啪啪免费 | 又大又粗又爽18禁免费看 | 天天舔天天摸 | 久久青青视频 | 久久天天躁狠狠躁夜夜躁2014 | 成人伊人 | 精品国产97 | 天天色天天干天天 | 99性视频| 嫩草一区二区三区 | 国产伦精品一区二区三区视频孕妇 | 爱逼av| 1024国产在线| 亚洲精品二 | 亚洲成人午夜影院 | 久久久久久久久99 | 欧洲精品久久一区二区 | 欧美三级特黄 | youjizz国产 | 日本黄色生活片 | 亚洲日日干 | 亚洲精品视频中文字幕 | 中文字幕狠狠干 | 中国黄色在线视频 | 午夜欧美精品 | 国产第99页 | 亚洲青青草原 | 国产寡妇色xxⅹ交肉视频 | 欧美特级aaa | 日韩一级黄 | 裸体女视频 | 一级大毛片 | 欧美极品一区 | 国产精品高潮呻吟久久aⅴ码 | 成人av网站在线观看 | 精品视频999 | 午夜精品久久久久久久96蜜桃 | av中文在线观看 | 骚虎av| 手机av免费在线 | 国产视频一区二区在线 | 国产精品美女在线 | 影音先锋制服 | 日韩专区在线播放 | 青娱乐在线免费观看 | 青青艹视频 | 欧美精品一区二区三区视频 | av青青草| 日韩精品一区二区三区四区 | 99福利在线 | 天天干天天搞天天射 | 国产在线观看免费视频今夜 | 福利在线免费 | 欧美色性视频 | 欧美精品成人一区二区三区四区 | 亚洲精品国产精品国自产网站 | 日韩欧美一级 | 亚洲911精品成人18网站 | 日韩无码精品一区二区三区 | 亚洲精品电影 | 国产又色又爽无遮挡免费动态图 | 日韩一级中文字幕 | www.久久婷婷 | 日韩黄色网址 | 成人午夜视频免费观看 | 欧美系列一区二区 | 青草一区 | 黑人极品videos精品欧美裸 | 亚洲精品一级二级 | 99热这里都是精品 | 天天干天天操天天拍 | 国产午夜精品一区二区三区嫩草 | 爱爱视频网站免费 | 特一级黄色大片 | 黄网站免费入口 | 亚洲av毛片 | 涩涩资源站 | 欧洲精品久久久久毛片完整版 | 亚洲精品久久久久久 | 欧美日韩高清 | 日韩精品一区二区三区国语自制 | 亚洲国产精品免费在线观看 | 亚洲日本在线播放 |