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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构与算法--二叉查找树转顺序排列双向链表

發布時間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法--二叉查找树转顺序排列双向链表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二叉查找樹轉順序排列雙向鏈表

  • 題目:輸入一顆二叉查找樹,將二叉查找樹轉成一個排序的雙向鏈表,要求不能創建任何新節點,只調整樹節點中指針的指向。例如下圖所示:
  • 本次二叉查找樹節點定義使用之前文章 數據結構與算法–二叉查找樹實現原理中節點定義,下文中相關api實現同樣使用該文中的方法,文中對二叉查找樹相關的api有詳細的說明推演,如有問題可到文中查看。節點實例如下:
/*** 二叉樹節點對象定義** @author liaojiamin* @Date:Created in 15:24 2020/12/11*/ public class BinaryNode implements Comparable {private Object element;private BinaryNode left;private BinaryNode right;private int count; ............
  • 理論基礎:

    • 二叉樹中節點與雙向鏈表的節點都存在兩個指針,只是指向不同而已。
    • 二叉搜索樹中左子節點總是小于主節點,右子節點總是大于主節點,在中序遍歷中就是順序的將每個節點讀取
    • 那么我們通過中序遍歷的思想將二叉查找樹轉順序雙向鏈表,將原先指向左節點的指針調整為鏈表的指向前一個節點,指向右節點的指針指向后一個節點
    • 如上方式得到我們轉換的結果
  • 問題分析:

    • 有關樹的題型我們必然會想到遞歸的,有樹遍歷必有遞歸,再者遞歸必然只考慮最簡單情況,這樣不至于將自己繞進去
    • 考慮三層節點最簡單情況,如上圖中,分三部分 10 根節點,6 為根節點的左子樹,14 為根節點的右子樹
    • 根據鏈表定義,10 節點將和左子樹的8 鏈接,和右子樹的12 鏈接
    • 也就是中序遍歷的順序 (4,6,8)–> 10 -->(12,14,16)
    • 左子樹為例,只需要增加兩個指針指向,4–>6, 8–>6 兩個指針,最后返回8 節點
    • 記錄當前節點為current,pLastNodeInList指向需要改變指向的節點,當遞歸到current = 6,左子樹pLastNodeInList指向最小節點4,只需要增加指針指向current.setleft = pLastNodeInList && pLastNodeInList.right=current,其實第一個是已經存在的,但是僅僅是左節點情況存在,我們左右節點統一處理,這樣用一個遞歸解決。接著回到上一節點pLastNodeInList = current = 6,
    • 繼續遞歸右子樹,current=8, current.left = pLastNodeInList = 6 && pLastNodeInList .right = current, 此處第二步驟指針已經存在,同樣統一處理。
    • 那么我們將每一個左,右子樹用同樣規則遞歸處理得到最終的結果,我們最終返回pLastNodeInList ,指向root節點
    • 在遞歸left方向得到鏈表頭
  • 圖解分析:

  • 通過如上分析有如下代碼:
/*** 二叉查找樹轉順序排列的雙向鏈表** @author liaojiamin* @Date:Created in 14:27 2021/5/19*/ public class ConvertBinaryToList {public static void main(String[] args) {BinaryNode node = new BinaryNode(null, null, null);BinarySearchTree searchTree = new BinarySearchTree();Random random = new Random();for (int i = 0; i < 8; i++) {node = searchTree.insert(random.nextInt(100), node);}printMiddle(node);BinaryNode doubleLink = convertBinary(node);BinaryNode headNode = doubleLink;while (headNode.getLeft() != null) {headNode = headNode.getLeft();}while (headNode.getRight() != null) {System.out.print("value: " + headNode.getElement());System.out.print("left: " + (headNode.getLeft() != null ? headNode.getLeft().getElement() : ""));System.out.print("right: " + (headNode.getRight() != null ? headNode.getRight().getElement() : ""));System.out.println();headNode = headNode.getRight();if(headNode.getRight() == null ){System.out.print("value: " + headNode.getElement());System.out.print("left: " + (headNode.getLeft() != null ? headNode.getLeft().getElement() : ""));System.out.print("right: " + (headNode.getRight() != null ? headNode.getRight().getElement() : ""));}}}/*** 二叉查找樹轉雙向鏈表,順序* 遞歸處理后,找出最左節點*/public static BinaryNode convertBinary(BinaryNode root) {BinaryNode pLastNodeInList = null;pLastNodeInList = convertNode(root, pLastNodeInList);BinaryNode pHeadOfLast = pLastNodeInList;while (pHeadOfLast != null && pHeadOfLast.getLeft() != null) {pHeadOfLast = pHeadOfLast.getLeft();}return pHeadOfLast;}public static BinaryNode convertNode(BinaryNode node, BinaryNode pLastNodeInList) {if (node == null) {return pLastNodeInList;}BinaryNode current = node;if (current.getLeft() != null) {//遞歸左節點pLastNodeInList = convertNode(current.getLeft(), pLastNodeInList);}//此時node節點是根,將左子樹的最大節點pLastNodeInList 設置為根的left節點current.setLeft(pLastNodeInList);if (pLastNodeInList != null) {//此時的pLastNodeInList 是左子樹的最大節點,他的right應該是root,也就是當前的currentpLastNodeInList.setRight(current);}//此時左節點干完,左節點的最大節點是當前root也就是currentpLastNodeInList = current;//遞歸右節點if (current.getRight() != null) {pLastNodeInList = convertNode(current.getRight(), pLastNodeInList);}return pLastNodeInList;}/*** 中序遍歷*/public static void printMiddle(BinaryNode root) {if (root == null || root.getElement() == null) {return;}printMiddle(root.getLeft());System.out.println(root.getElement());printMiddle(root.getRight());}}

上一篇:數據結構與算法–復雜鏈表的復制
下一篇:數據結構與算法–字符串的排列組合問題

總結

以上是生活随笔為你收集整理的数据结构与算法--二叉查找树转顺序排列双向链表的全部內容,希望文章能夠幫你解決所遇到的問題。

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