題目描述
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
題目分析
- 二叉樹中每個節點都有兩個指向子節點的指針;
- 在雙向鏈表中,每個節點也有兩個指針,分別指向前一個節點和後一個節點;
- 在將二叉樹轉換成雙向鏈表時,原先指向左子節點的指針調整爲鏈表中指向前一個節點的指針,原先指向右子節點的指針調整爲鏈表中指向後一個節點的指針。
概念
1、二叉搜索樹:二叉搜索樹(英語:Binary Search Tree),也稱二叉查找樹、有序二叉樹(英語:ordered binary tree),排序二叉樹(英語:sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:
- 任意節點,如果左子樹不爲空,則左子樹上所有結點的值均小於它的根結點的值;
- 任意節點,如果右子樹不爲空,則右子樹上所有結點的值均大於它的根結點的值;
- 任意節點的左、右子樹也分別爲二叉查找樹;
- 沒有鍵值相等的節點。
解題思路
由於二叉搜索樹的特點,可以看出其中序遍歷的結果是從小到大訪問節點的,正好符合鏈表有序的要求,所以可以藉助中序遍歷的過程來完成二叉樹到鏈表的轉換過程,可以採用遞歸進行處理。
每次在遞歸遍歷的時候設置一個pre,記錄中序遍歷時當前訪問節點(node)的前一個節點,然後將當前節點的左指針指向pre,然後如果pre節點不爲空則將pre的右節點指向當前節點,由此就形成了一個雙向鏈表的前後指針。每次遞歸重複這兩步,則可以形成一個完整的雙向鏈表。最後一步就是雙向鏈表已經構建完成了,而題目要求返回雙向鏈表,則往前遍歷找到雙向鏈表的頭返回即可。
代碼
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if( pRootOfTree == NULL )
return NULL;
help( pRootOfTree );
while( pre->left != NULL )
pre = pre->left;
return pre;
}
TreeNode* pre = NULL;
void help( TreeNode* node )
{
if( node == NULL )
return;
if( pre == NULL && node->left == NULL )
pre = node;
help( node->left );
if( pre != NULL && pre != node )
{
// pre爲上一個節點,node爲當前節點
pre->right = node;
node->left = pre;
pre = node;
}
help(node->right);
return;
}
};