国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

尋找二叉樹的下一個節(jié)點

開發(fā) 前端
已知一個包含父節(jié)點引用的二叉樹和其中的一個節(jié)點,如何找出這個節(jié)點中序遍歷序列的下一個節(jié)點?

本文轉載自微信公眾號「神奇的程序員k」,作者神奇的程序員K。轉載本文請聯(lián)系神奇的程序員k公眾號。  

前言

已知一個包含父節(jié)點引用的二叉樹和其中的一個節(jié)點,如何找出這個節(jié)點中序遍歷序列的下一個節(jié)點?

本文就跟大家分享下這個問題的解決方案與實現代碼,歡迎各位感興趣的開發(fā)者閱讀本文。

問題分析

正如前言所述,我們的已知條件如下:

  • 包含父節(jié)點引用的二叉樹
  • 要查找的節(jié)點

我們要解決的問題:

  • 找出要查找節(jié)點中序遍歷序列的下一個節(jié)點

接下來,我們通過舉例來推導下一個節(jié)點的規(guī)律,我們先來畫一顆二叉搜索樹,如下所示:

  1.  
  2.    / \ 
  3.   6   13 
  4.  / \  / \ 
  5. 3  7 9  15 

例如,我們尋找6的下一個節(jié)點,根據中序遍歷的規(guī)則我們可知它的下一個節(jié)點是7

  • 8的下一個節(jié)點是9
  • 3的下一個節(jié)點是6
  • 7的下一個節(jié)點是8

通過上述例子,我們可以分析出下述信息:

  • 要查找的節(jié)點存在右子樹,那么它的下一個節(jié)點就是其右子樹中的最左子節(jié)點
  • 要查找的節(jié)點不存右子樹:
    • 當前節(jié)點屬于父節(jié)點的左子節(jié)點,那么它的下一個節(jié)點就是其父節(jié)點本身
    • 當前節(jié)點屬于父節(jié)點的右子節(jié)點,那么就需要沿著父節(jié)點的指針一直向上遍歷,直至找到一個是它父節(jié)點的左子節(jié)點的節(jié)點

上述規(guī)律可能有點繞,大家可以將規(guī)律代入問題中多驗證幾次,就能理解了。

實現思路

  • 二叉樹中插入節(jié)點時保存其父節(jié)點的引用
  • 調用二叉樹的搜索節(jié)點方法,找到要查找的節(jié)點信息
  • 判斷找到的節(jié)點是否存在右子樹
  • 如果存在,則遍歷它的左子樹至葉節(jié)點,將其返回。
  • 如果不存在,則遍歷它的父節(jié)點至根節(jié)點,直至找到一個節(jié)點與它父節(jié)點的左子節(jié)點相等的節(jié)點,將其返回。

實現代碼

接下來,我們將上述思路轉換為代碼,本文代碼中用到的二叉樹相關實現請移步我的另一篇文章:TypeScript實現二叉搜索樹

搜索要查找的節(jié)點

我們需要找到要查找節(jié)點在二叉樹中的節(jié)點信息,才能繼續(xù)實現后續(xù)步驟,搜索節(jié)點的代碼如下:

  1. import { Node } from "./Node.ts"
  2.  
  3. export default class BinarySearchTree<T> { 
  4.     protected root: Node<T> | undefined; 
  5.  
  6.     constructor(protected compareFn: ICompareFunction<T> = defaultCompare) { 
  7.         this.root = undefined; 
  8.     } 
  9.    
  10.     // 搜索特定值 
  11.     search(key: T): boolean | Node<T> { 
  12.         return this.searchNode(<Node<T>>this.root, key); 
  13.     } 
  14.  
  15.     // 搜索節(jié)點 
  16.     private searchNode(node: Node<T>, key: T): boolean | Node<T> { 
  17.         if (node == null) { 
  18.             return false
  19.         } 
  20.  
  21.         if (this.compareFn(key, node.key) === Compare.LESS_THAN) { 
  22.             // 要查找的key在節(jié)點的左側 
  23.             return this.searchNode(<Node<T>>node.leftkey); 
  24.         } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { 
  25.             // 要查找的key在節(jié)點的右側 
  26.             return this.searchNode(<Node<T>>node.rightkey); 
  27.         } else { 
  28.             // 節(jié)點已找到 
  29.             return node; 
  30.         } 
  31.     } 

保存父節(jié)點引用

此處的二叉樹與我們實現的二叉樹稍有不同,插入節(jié)點時需要保存父節(jié)點的引用,實現代碼如下:

  1. export default class BinarySearchTree<T> { 
  2.     // 插入方法 
  3.     insert(key: T): void { 
  4.         if (this.root == null) { 
  5.             // 如果根節(jié)點不存在則直接新建一個節(jié)點 
  6.             this.root = new Node(key); 
  7.         } else { 
  8.             // 在根節(jié)點中找合適的位置插入子節(jié)點 
  9.             this.insertNode(this.root, key); 
  10.         } 
  11.     } 
  12.    
  13.     // 節(jié)點插入 
  14.     protected insertNode(node: Node<T>, key: T): void { 
  15.         // 新節(jié)點的鍵小于當前節(jié)點的鍵,則將新節(jié)點插入當前節(jié)點的左邊 
  16.         // 新節(jié)點的鍵大于當前節(jié)點的鍵,則將新節(jié)點插入當前節(jié)點的右邊 
  17.         if (this.compareFn(key, node.key) === Compare.LESS_THAN) { 
  18.             if (node.left == null) { 
  19.                 // 當前節(jié)點的左子樹為null直接插入 
  20.                 node.left = new Node(key, node); 
  21.             } else { 
  22.                 // 從當前節(jié)點(左子樹)向下遞歸,找到null位置將其插入 
  23.                 this.insertNode(node.leftkey); 
  24.             } 
  25.         } else { 
  26.             if (node.right == null) { 
  27.                 // 當前節(jié)點的右子樹為null直接插入 
  28.                 node.right = new Node(key, node); 
  29.             } else { 
  30.                 // 從當前節(jié)點(右子樹)向下遞歸,找到null位置將其插入 
  31.                 this.insertNode(node.rightkey); 
  32.             } 
  33.         } 
  34.     } 
  35.  
  36. /** 
  37.  * 二叉樹的輔助類: 用于存儲二叉樹的每個節(jié)點 
  38.  */ 
  39. export class Node<K> { 
  40.     public left: Node<K> | undefined; 
  41.     public right: Node<K> | undefined; 
  42.     public parent: Node<K> | undefined; 
  43.     constructor(public key: K, parent?: Node<K>) { 
  44.         this.left = undefined; 
  45.         this.right = undefined; 
  46.         console.log(key"的父節(jié)點", parent?.key); 
  47.         this.parent = parent; 
  48.     } 
  49.  
  50.     toString(): string { 
  51.         return `${this.key}`; 
  52.     } 

我們來測試下上述代碼,驗證下父節(jié)點引用是否成功:

  1. const tree = new BinarySearchTree(); 
  2. tree.insert(8); 
  3. tree.insert(6); 
  4. tree.insert(3); 
  5. tree.insert(7); 
  6. tree.insert(13); 
  7. tree.insert(9); 
  8. tree.insert(15); 

 

在保存父節(jié)點引用時折騰了好久也沒實現,最后求助了我的朋友_Dreams😁。

尋找下一個節(jié)點

接下來,我們就可以根據節(jié)點的規(guī)律來實現這個算法了,實現代碼如下:

  1. export class TreeOperate<T> { 
  2.     /** 
  3.      * 尋找二叉樹的下一個節(jié)點 
  4.      * 規(guī)則: 
  5.      *  1. 輸入一個包含父節(jié)點引用的二叉樹和其中的一個節(jié)點 
  6.      *  2. 找出這個節(jié)點中序遍歷序列的下一個節(jié)點 
  7.      * 
  8.      * 例如: 
  9.      *       8 
  10.      *      / \ 
  11.      *     6   13 
  12.      *    / \  / \ 
  13.      *   3  7 9  15 
  14.      * 
  15.      * 6的下一個節(jié)點是7,8的下一個節(jié)點是9 
  16.      * 
  17.      * 通過分析,我們可以得到下述信息: 
  18.      *  1. 如果一個節(jié)點有右子樹,那么它的下一個節(jié)點就是其右子樹中的最左子節(jié)點 
  19.      *  2. 如果一個節(jié)點沒有右子樹: 
  20.      *  (1). 當前節(jié)點屬于父節(jié)點的左子節(jié)點,那么它的下一個節(jié)點就是其父節(jié)點本身 
  21.      *  (2). 當前節(jié)點屬于父節(jié)點的右子節(jié)點,沿著父節(jié)點的指針一直向上遍歷,直至找到一個是它父節(jié)點的左子節(jié)點的節(jié)點 
  22.      * 
  23.      */ 
  24.     findBinaryTreeNextNode(tree: BinarySearchTree<number>, node: number): null | Node<number> { 
  25.         // 搜索節(jié)點 
  26.         const result: Node<number> | boolean = tree.search(node); 
  27.         if (result == null) throw "節(jié)點不存在"
  28.         let currentNode = result as Node<number>; 
  29.         // 右子樹存在 
  30.         if (currentNode.right) { 
  31.             currentNode = currentNode.right
  32.             // 取右子樹的最左子節(jié)點 
  33.             while (currentNode.left) { 
  34.                 currentNode = currentNode.left
  35.             } 
  36.             return currentNode; 
  37.         } 
  38.  
  39.         // 右子樹不存在 
  40.         while (currentNode.parent) { 
  41.             // 當前節(jié)點等于它父節(jié)點的左子節(jié)點則條件成立 
  42.             if (currentNode === currentNode.parent.left) { 
  43.                 return currentNode.parent; 
  44.             } 
  45.             // 條件不成立,繼續(xù)獲取它的父節(jié)點 
  46.             currentNode = currentNode.parent; 
  47.         } 
  48.         return null
  49.     } 

我們通過一個例子來測試下上述代碼:

  1. // 構建二叉搜索樹 
  2. const tree = new BinarySearchTree(); 
  3. tree.insert(8); 
  4. tree.insert(6); 
  5. tree.insert(3); 
  6. tree.insert(7); 
  7. tree.insert(13); 
  8. tree.insert(9); 
  9. tree.insert(15); 
  10. // 尋找下一個節(jié)點 
  11. const nextNode = treeOperate.findBinaryTreeNextNode(tree, 7); 
  12. console.log("7的下一個節(jié)點", nextNode.toString()); 

 

 

 

 

代碼地址

文中完整代碼如下:

  • TreeOperate.ts
  • BinarySearchTree.ts

 

責任編輯:武曉燕 來源: 神奇的程序員k
相關推薦

2020-04-27 07:05:58

二叉樹左子樹右子樹

2021-07-16 08:57:31

迭代遍歷二叉樹

2021-05-06 17:46:30

二叉樹數據結構

2021-04-20 08:37:14

數據結構二叉樹

2021-04-19 07:47:42

數據結構二叉樹Tree

2021-04-28 20:12:27

數據結構創(chuàng)建

2021-08-27 11:36:44

二叉樹回溯節(jié)點

2021-09-29 10:19:00

算法平衡二叉樹

2021-12-17 14:26:58

二叉樹節(jié)點數量

2022-10-26 23:58:02

二叉樹數組算法

2021-11-29 10:40:58

二叉樹鏡像節(jié)點

2020-09-23 18:25:40

算法二叉樹多叉樹

2013-07-15 16:35:55

二叉樹迭代器

2021-03-17 08:19:22

二叉樹LeetCode

2021-12-05 18:25:12

二叉樹路徑節(jié)點

2021-09-15 07:56:32

二叉樹層次遍歷

2021-10-12 09:25:11

二叉樹樹形結構

2022-10-12 23:25:17

二叉樹父節(jié)點根節(jié)點

2021-03-22 08:23:29

LeetCode二叉樹節(jié)點

2023-05-08 15:57:16

二叉樹數據結構
點贊
收藏

51CTO技術棧公眾號

欧美日韩另类在线| 日本视频久久久| 一区二区电影网| 久久精品在线观看| 男人天堂999| 26uuu亚洲综合色| 99999精品视频| 91网站在线观看视频| 日韩avxxx| 中文字幕不卡的av| 91传媒在线观看| 成人h版在线观看| ·天天天天操| 久久青草精品视频免费观看| 国产美女精品人人做人人爽| 狠狠久久亚洲欧美专区| 国产精品字幕| 日韩电影大全免费观看2023年上| 一区二区成人网| 欧美日韩亚洲高清一区二区| 国产专区欧美精品| 欧美日韩电影一区二区三区| 日本中文在线一区| 午夜精品久久久久久久久久久久| 精品一区二区三区视频| 久久久久久久久久久久久久一区| 国产精品videosex极品| 国产日韩欧美一二三区| 91.麻豆视频| 青春草在线免费视频| 精品国精品国产| 三上悠亚激情av一区二区三区| 播播国产欧美激情| 综合综合综合综合综合网| dy888夜精品国产专区| 蜜桃av噜噜一区二区三区小说| 中文字幕一区二区三区四区五区人| 9久草视频在线视频精品| 好吊妞这里只有精品| 欧美日韩国产另类一区| 在线看片福利| 97精品欧美一区二区三区| 欧美日本三区| 少妇无码av无码专区在线观看 | 成人信息集中地欧美| 久久黄色网页| 丝袜老师办公室里做好紧好爽| 亚洲最色的网站| 日本三级在线观看网站| 久久久久免费视频| 在线日韩av| 男女日批视频在线观看| 亚洲黄色免费电影| 久色国产在线| 日韩69视频在线观看| 日韩va亚洲va欧美va久久| 九色porny91| 欧美一二三区精品| 97色成人综合网站| 日韩videos| 亚洲精品美腿丝袜| 爱啪啪综合导航| 国产精品夜间视频香蕉| 国产精品88888| 污视频网站在线免费观看| 中国china体内裑精亚洲片| 奇米影视亚洲| 久久国产精品网| 欧美日韩国产天堂| 欧美精品国产精品日韩精品| 亚洲精品在线观看91| 亚洲一区综合| 久久久久久久久一| 污污网站在线| 91精品国产高清久久久久久久久 | 亚洲欧美另类图片小说| 三级无遮挡在线观看| 亚洲欧美日韩精品久久亚洲区 | 国产69精品久久久久9999| 国产成人午夜视频| 四虎国产精品永远| 中文字幕乱码人妻综合二区三区 | 视频在线日韩| 91中文字幕在线观看| 欧美日韩五码| 亚洲最大福利网站| 欧美高清在线一区| 国内揄拍国内精品久久| 国产精品不卡一区| 男女在线视频| 91网站免费看| 欧美国产禁国产网站cc| 国产无遮挡裸体视频在线观看| 亚洲一区中文字幕在线观看| 国产日韩欧美高清| 国产另类xxxxhd高清| 日韩av一区二区三区在线观看| 精品久久久免费| 牛牛影视久久网| 熟女人妇 成熟妇女系列视频| 日韩av在线免费观看| 99精品热视频只有精品10| 在线观看污污视频| 久久久免费电影| 中文在线最新版天堂8| 国产欧美日韩中文字幕| 欧美日韩视频专区在线播放| 成人国产电影网| 国产欧美日韩精品一区二区三区| 噼里啪啦在线中文观看| 国内揄拍国内精品久久| 黄色污网站在线免费观看| 欧美成人一区二区在线| 色88888久久久久久影院野外| 国产成都精品91一区二区三| 91麻豆精品国产91久久久久 | 亚洲一区尤物| 精品国产免费一区二区三区香蕉| 欧美日韩亚洲91| 91中文在线| 一区二区国产精品| 成人综合日日夜夜| 欧美成人app| 黄色成人在线网站| 欧美精品视频www在线观看| 久久男人资源视频| 中文字幕色呦呦| 蜜芽在线免费观看| 大奶一区二区三区| 欧美激情性爽国产精品17p| 国产一卡不卡| 性色一区二区| 中文不卡在线| 有码一区二区三区| 一区二区三区免费看视频| 欧美中文字幕一二三区视频| 中文字幕久久久av一区| 亚洲视频在线看| 日韩av在线网址| 日韩不卡中文字幕| 2018国产精品视频| 天美星空大象mv在线观看视频| 丰满大乳少妇在线观看网站| 日韩在线观看不卡| 99久久人爽人人添人人澡| 伊人久久亚洲美女图片| 国产精品无圣光一区二区| 国产精品自在在线| 亚洲激情六月丁香| 亚洲片在线资源| 成人免费午夜电影| 永久免费毛片在线播放不卡 | 欧美欧美黄在线二区| 精品视频二区| 黄页免费观看| 麻豆视频在线免费观看| 午夜久久中文| 久久香蕉国产| 亚洲一区精品在线| 日韩av片免费在线观看| 成人免费高清观看| 亚洲激情欧美激情| 欧美不卡在线一区二区三区| 国内少妇毛片视频| 欧美日韩黄色一级片| 午夜激情在线观看视频| 成年人视频网站在线| 性欧美videoshd高清| 黄色的视频在线观看| 美女写真久久影院| 精品国产乱码久久久久久果冻传媒| 亚洲国产aⅴ精品一区二区| 日韩黄色一级片| 欧美videos大乳护士334| 国产美女扒开尿口久久久| 亚洲三级一区| 青青久久av| 亚洲自拍另类综合| 91国自产精品中文字幕亚洲| 国产黄视频在线观看| 欧美激情另类| 亚洲一区二区三区小说| 欧美日韩大陆在线| 成人短视频在线看| 波多野吉衣av| av中文一区| 亚洲国产一二三| 久久99国产精品自在自在app | 蜜臀av在线播放一区二区三区| 亚洲国产精品久久久久秋霞不卡| 欧美日韩天天操| 免费看a在线观看| 亚洲第一福利专区| 亚洲人成网站色在线观看| 久久综合入口| 精品久久在线| 色喇叭免费久久综合网| 精品视频在线免费看| 亚洲成人第一| 99精品国产高清一区二区|