標籤:
題目:輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向鏈表。要求不能建立新的結點,只能調整樹中結點指標的指向。
比如如中的二叉搜尋樹,則輸出轉換之後的排序雙向鏈表為:
在二叉樹中,每個結點都有兩個指向子節點的指標。在雙向鏈表中,每個結點也有兩個指標,他們分別指向前一個結點和後一個結點。由於這兩種結點的結構相似,同時二叉搜尋樹也是一種排序的資料結構,因此在理論上有可能實現二叉搜尋樹和排序的雙向鏈表的轉換。在搜尋二叉樹中,左子結點的值總是小於父節點的值,右子節點的值總是大於父節點的值。因此我們在轉換稱排序的雙向鏈表時,原先指向的左子結點的指標調整為鏈表中指向前一個結點的指標,原先指向右子節點的指標調整為倆表為指向後一個結點的指標。接下來我們考慮如何轉化。
由於要求轉換之後的鏈表是排好序的,我們可疑中序遍曆樹中的每一個結點,這是因為中序遍曆演算法的特點是按照從小到達的順序遍曆二叉樹的每一個結點。當遍曆到根節點的時候,我們把樹堪稱三部分:值為10的結點,根節點為6的左子樹、根節點為14的右子樹。根據排序鏈表的定義,值為10的結點將和它的左子樹的最大的一個結點(即值為8的結點)連結起來,同時它還將和右子樹最小的結點(即值為12的結點)連結起來,
按照中序遍曆的順序,當我們遍曆轉換到根節點(值為10的結點)時,它的左子樹已經轉換成一個排序的鏈表了,並且處在鏈表中的最後一個結點是當前值的最大的結點。我們把值為8的結點根節點連結起來,此時鏈表中的最後一個結點是10了。接著我們去遍曆轉換右子樹,並把根節點和右子樹最小的結點連結起來。至於怎麼去轉換它的左子樹和右子樹,由於遍曆和轉換過程是一樣的,我們自然的想到了遞迴。
Java代碼實現:
/** * 輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向鏈表。 * 要求不能建立任何新的結點,只能調整樹中結點指標的指向。 */package swordForOffer;import utils.BinaryTreeNode;/** * @author JInShuangQi * * 2015年8月6日 */public class E27ConvertBinarySearchTree {public BinaryTreeNode convert(BinaryTreeNode root){BinaryTreeNode node = null;convert(root,node);while(node != null && node.leftNode != null){node = node.leftNode;}return node;}public void convert(BinaryTreeNode root,BinaryTreeNode lastNode){if(root == null)return;BinaryTreeNode current = root;if(current.leftNode != null)convert(current.leftNode,lastNode);current.leftNode = lastNode;if(lastNode != null)lastNode.rightNode = current;if(current.rightNode != null)convert(current.rightNode,lastNode);}}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
劍指Offer面試題27(Java版):二叉搜尋樹與雙向鏈表