劍指Offer——二叉搜索樹與雙向鏈表

題目描述

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

題目分析

  • 二叉樹中每個節點都有兩個指向子節點的指針;
  • 在雙向鏈表中,每個節點也有兩個指針,分別指向前一個節點和後一個節點;
  • 在將二叉樹轉換成雙向鏈表時,原先指向左子節點的指針調整爲鏈表中指向前一個節點的指針,原先指向右子節點的指針調整爲鏈表中指向後一個節點的指針。


概念

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;
    }
};
發佈了52 篇原創文章 · 獲贊 54 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章