【Java】 劍指offer(36) 二叉搜索樹與雙向鏈表
阿新 • • 發佈:2018-10-27
當前 返回 收獲 要求 pre 設置 輸入 val 思考
本文參考自《劍指offer》一書,代碼采用Java語言。
更多:《劍指Offer》Java實現合集
題目
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
思路
二叉搜索樹、排序鏈表,想到使用中序遍歷。
要實現雙向鏈表,必須知道當前結點的前一個結點。根據中序遍歷可以知道,當遍歷到根結點的時候,左子樹已經轉化成了一個排序的鏈表了,根結點的前一結點就是該鏈表的最後一個結點(這個結點必須記錄下來,將遍歷函數的返回值設置為該結點即可),鏈接根結點和前一個結點,此時鏈表最後一個結點就是根結點了。再處理右子樹,遍歷右子樹,將右子樹的最小結點與根結點鏈接起來即可。左右子樹的轉化采用遞歸即可。
大概思想再理一下:首先想一下中序遍歷的大概代碼結構(先處理左子樹,再處理根結點,之後處理右子樹),假設左子樹處理完了,就要處理根結點,而根結點必須知道左子樹的最大結點,所以要用函數返回值記錄下來;之後處理右子樹,右子樹的最小結點(也用中序遍歷得到)要和根結點鏈接。
測試算例
1.功能測試(一個結點;左右斜樹;完全二叉樹;普通二叉樹)
2.特殊測試(根結點為null)
Java代碼
//題目:輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求 //不能創建任何新的結點,只能調整樹中結點指針的指向。 public class ConvertBinarySearchTree { public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } public TreeNode convert(TreeNode head) { if(head==null) return head; TreeNode lastNodeInList=null; lastNodeInList=convertHelper(head,lastNodeInList); TreeNode firstNodeInList=lastNodeInList; while(firstNodeInList.left!=null) { firstNodeInList=firstNodeInList.left; } return firstNodeInList; } private TreeNode convertHelper(TreeNode node,TreeNode lastNode) { //處理左子樹,獲得最大結點 if(node.left!=null) lastNode=convertHelper(node.left, lastNode); //鏈接最大結點和根結點 node.left=lastNode; if(lastNode!=null) lastNode.right=node; //處理右子樹 lastNode=node; if(node.right!=null) lastNode=convertHelper(node.right, lastNode); return lastNode; } }
收獲
題目較復雜時,不要慌。這道題和中序遍歷有關,把樹分為三部分:根結點、左子樹和右子樹,思考在中序遍歷中根結點應該如何處理,這是關鍵——要將左子樹的最大結點、根結點、右子樹的最小結點鏈接起來。左右子樹的處理是相同的,因此采用遞歸。
更多:《劍指Offer》Java實現合集
【Java】 劍指offer(36) 二叉搜索樹與雙向鏈表