zoukankan      html  css  js  c++  java
  • 剑指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 };
  • 相关阅读:
    python报以下错误:TypeError: 'int' object is not subscriptable
    C# Func与Action
    C#调用C++的DLL 尝试写入受保护的内存
    C#调用C++的dll EntryPointNotFoundException
    C# 拖拽事件
    C#操作Access数据库中遇到的问题(待续)
    Winform 中写代码布局中遇到的控件遮盖问题
    thinkphp6执行流程(一)
    xdebug调试过程中apache500超时
    禁用phpcookie以后如何使用Session
  • 原文地址:https://www.cnblogs.com/rookiez/p/13235621.html
Copyright © 2011-2022 走看看