剑指offer 二叉搜索树与双向链表

二叉搜索树与双向链表

题目描述

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

我的解答

思路

这道题目有一个关键的思想就是化繁为简,也就是将一个复杂的问题简单化,这里就是根节点连接到左子树最右边一个节点,同时将右子树连接到最左边一个节点。以此类推。这道题目我原来入了一个坑,就是自上而下建立双链表,建立到下面后出现指针混乱,所以这道题目只可以自下而上建立双链表。

代码

//
//  main.cpp
//  offer26
//
//  Created by 李林 on 16/7/25.
//  Copyright © 2016年 李林. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;

struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :val(x), left(NULL), right(NULL) {
    }
};

class Solution {
public:

    TreeNode* Insert(TreeNode* root, int value){
        if(root==NULL)
            root = new TreeNode(value);
        else{
            if(root->val>value)
                root->left = Insert(root->left, value);
            else
                root->right = Insert(root->right, value);
        }
        return root;
    }

    TreeNode* Convert(TreeNode* pRootOfTree){
        if(pRootOfTree==NULL)
            return NULL;
        //暂存
        TreeNode* Left = pRootOfTree->left;
        TreeNode* Right = pRootOfTree->right;

        //这里先进行递归,下面进行操作,存在链接混乱的问题。
        //也就是先从的层开始,自下而上。
        if((Left!=NULL) && (Left->left!=NULL || Left->right!=NULL))
            Convert(Left);
        if((Right!=NULL) && (Right->left!=NULL || Right->right!=NULL))
            Convert(Right);

        //获取左子树最右边节点和右子树最左边节点。
        if(pRootOfTree->left){
            TreeNode* leftTree;
            leftTree = pRootOfTree->left;
            while(leftTree->right != NULL)
                leftTree = leftTree->right;
            //join left
            leftTree->right = pRootOfTree;
            pRootOfTree->left = leftTree;

        }

        if(pRootOfTree->right){
            TreeNode* rightTree;
            rightTree = pRootOfTree->right;
            while(rightTree->left != NULL)
                rightTree = rightTree->left;
            //join right
            rightTree->left = pRootOfTree;
            pRootOfTree->right = rightTree;
        }

        TreeNode* res;
        while(pRootOfTree->left!=NULL)
            pRootOfTree = pRootOfTree->left;
        return pRootOfTree;
    }

    //中序非递归
    void InOrderTraverse(TreeNode* root){
        stack<TreeNode*> st;
        if(root==NULL){
            printf("Empty Tree");
            return ;
        }

        while(root || !st.empty()){
            while(root){
                st.push(root);
                root = root->left;
            }
            root = st.top();
            st.pop();
            printf("%d ", root->val);
            root = root->right;
        }

    }

    //中序递归
    void InOrder(TreeNode* root){
        if(root->left)  InOrder(root->left);
        printf("%d ", root->val);
        if(root->right) InOrder(root->right);
    }

    void LinkListTraverse(TreeNode * root){

        while(root!=NULL){
            printf("%d ", root->val);
            root = root->right;
        }
    }

};

int main() {
    Solution s;
    TreeNode* root = NULL;
    int array[] = {4,2,6,1};

    for(int i=0; i<4; i++)
        root = s.Insert(root, array[i]);
    s.InOrderTraverse(root);

    TreeNode* res = s.Convert(root);
    s.LinkListTraverse(res);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值