生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法--二叉查找树转顺序排列双向链表
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二叉查找樹轉順序排列雙向鏈表
- 題目:輸入一顆二叉查找樹,將二叉查找樹轉成一個排序的雙向鏈表,要求不能創建任何新節點,只調整樹節點中指針的指向。例如下圖所示:
- 本次二叉查找樹節點定義使用之前文章 數據結構與算法–二叉查找樹實現原理中節點定義,下文中相關api實現同樣使用該文中的方法,文中對二叉查找樹相關的api有詳細的說明推演,如有問題可到文中查看。節點實例如下:
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方向得到鏈表頭
-
圖解分析:
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
);}current
.setLeft(pLastNodeInList
);if (pLastNodeInList
!= null
) {pLastNodeInList
.setRight(current
);}pLastNodeInList
= 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());}}
上一篇:數據結構與算法–復雜鏈表的復制
下一篇:數據結構與算法–字符串的排列組合問題
總結
以上是生活随笔為你收集整理的数据结构与算法--二叉查找树转顺序排列双向链表的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。