代码改变世界

将二叉搜索树转为有序双向链表

2016-09-28 09:58  明星bigdata  阅读(652)  评论(0编辑  收藏  举报

部分转载自http://blog.csdn.net/sgbfblog/article/details/7939589

题目描述

给定一棵二叉排序树(BST),将该树转换成一棵双向循环链表。请看下面的图示说明,你可以更清楚的了解题意。

BST的结构定义如下:

struct node {  
    int data;  
    
node* left;
    node* right; }; typedef struct node Node;

 

 

                                     图1)一棵存储1-5的二叉搜索树(BST)

 

        图2)根据上面的BST转换得到的有序循环链表。其中,树的左右孩子指针替换成了pre和next指针,分别指向链表的前一个和后一个结点。

 

c++的代码如下:

#include <iostream>

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

using namespace std;

TreeNode * treeToDoublyList(TreeNode * root);
void treeToDoublyList(TreeNode ** p, TreeNode ** pre, TreeNode ** head);

int main()
{
    TreeNode * root = new TreeNode(5);
    TreeNode * layer1_node1 = new TreeNode(3);
    TreeNode * layer1_node2 = new TreeNode(7);
    TreeNode * layer2_node1 = new TreeNode(1);
    TreeNode * layer2_node2 = new TreeNode(4);
    TreeNode * layer2_node3 = new TreeNode(9);

    root->left = layer1_node1;
    root->right = layer1_node2;

    layer1_node1->left = layer2_node1;
    layer1_node1->right = layer2_node2;

    layer1_node2->right = layer2_node3;

    TreeNode * temp = treeToDoublyList(root);

    TreeNode * head = temp;
    while (temp->right != head)
    {
        cout << temp->val << endl;
        temp = temp->right;
    }
    cout << temp->val << endl;
    cout << "Hello world!" << endl;
    //system("pause");
    return 0;
}

TreeNode * treeToDoublyList(TreeNode * root)
{
    TreeNode * head = NULL;
    TreeNode * pre = NULL;
    treeToDoublyList(&root, &pre, &head);
    //cout << "fun 2 over! head value: " << head->val << endl;
    return head;
}

void treeToDoublyList(TreeNode ** p, TreeNode ** pre, TreeNode ** head)
{
    if (!(*p))
        return;
    treeToDoublyList(&((*p)->left), pre, head);
    (*p)->left = *pre;
    if (*pre)
    {
        //cout << (*pre)->val << endl;
        (*pre)->right = *p;
    }

    else
        *head = *p;
    TreeNode * r = (*p)->right;
    (*p)->right = *head;
    (*head)->left = *p;
    *pre = *p;
    treeToDoublyList(&r, pre, head);

}

 原博主的代码粗略看上去和我的代码没什么区别,但是其实不然,我在自己实现的时候第一个版本的代码也是如原博主的代码一样,但是很不幸出了bug,经过debug我发现问题出在函数调用过程中,C++默认进行传值,而java中非基本类型默认船引用!所以看了《进军硅谷》的书中用java实现的代码,自己再用c++实现,很容易掉入这个坑!所以要注意C++和java的区别,java底层其实用指针实现,对于非基本数据类型,默认传引用,这使得java的代码看上去比c++的代码清晰简洁,至少不需要C++的二重指针,而且减少了错误的发生。但是为了这种看上去的简洁,java的在效率上的牺牲也是巨大的。