剑指36 二叉搜索书与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

为了让您更好地理解问题,以下面的二叉搜索树为例:

 

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

LeetCode这一题和书上稍有不同,LeetCode需要把链表头尾链接起来。

一开始以为直接按中序遍历调整一下指针就可以了,但是并不是这样,每个节点左侧连接的是左子树的最大值节点,右侧链接的是右子树的最小值节点,并不一定是原本的左右子节点。

这个题采用递归的方法,先处理好左子树,连接当前节点和左子树;再处理好右子树,链接当前节点和右子树。最后连接头尾。

分别定义两个函数,处理左子树和右子树。处理左子树函数需要返回处理后的链表的最大值,即链表尾;处理右子树函数需要返回处理后的链表的最小值,即链表头。

注意在当前节点连接到了左子节点或者右子节点后,子节点也要反向连接到当前节点。如果没有这一步,那么所有叶子节点的两个指针都是null,这样链表就断开了,一开始犯了这个错误。

不要忘记处理根节点为空的情况。

 1 /*
 2 // Definition for a Node.
 3 class Node {
 4 public:
 5     int val;
 6     Node* left;
 7     Node* right;
 8 
 9     Node() {}
10 
11     Node(int _val) {
12         val = _val;
13         left = NULL;
14         right = NULL;
15     }
16 
17     Node(int _val, Node* _left, Node* _right) {
18         val = _val;
19         left = _left;
20         right = _right;
21     }
22 };
23 */
24 class Solution {
25 public:
26     Node* treeToDoublyList(Node* root) {
27         if(root==nullptr)
28             return root;
29         if(root->left!=nullptr){
30             root->left=convert_left(root->left);
31             root->left->right=root;
32         }
33         if(root->right!=nullptr){
34             root->right=convert_right(root->right);
35             root->right->left=root;
36         }
37         Node* leftside=root,*rightside=root;
38         while(leftside->left!=nullptr)
39             leftside=leftside->left;
40         while(rightside->right!=nullptr)
41             rightside=rightside->right;
42         leftside->left=rightside;
43         rightside->right=leftside;
44        
45         return leftside;
46     }
47 
48     Node* convert_left(Node* cur_node){//返回该子树中最大的节点
49         if(cur_node->left!=nullptr){
50             cur_node->left=convert_left(cur_node->left);
51             cur_node->left->right=cur_node;
52         }
53         if(cur_node->right!=nullptr){
54             cur_node->right=convert_right(cur_node->right);
55             cur_node->right->left=cur_node;
56         }
57         while(cur_node->right!=nullptr)
58             cur_node=cur_node->right;
59         return cur_node;
60     }
61 
62     Node* convert_right(Node* cur_node){//返回该子树中最小的节点
63         if(cur_node->left!=nullptr){
64             cur_node->left=convert_left(cur_node->left);
65             cur_node->left->right=cur_node;
66         }
67         if(cur_node->right!=nullptr){
68             cur_node->right=convert_right(cur_node->right);
69             cur_node->right->left=cur_node;
70         }
71         while(cur_node->left!=nullptr)
72             cur_node=cur_node->left;
73         return cur_node;
74     }
75 };
原文地址:https://www.cnblogs.com/rookiez/p/13235621.html