Vanilla Sky

   相信自己,但不可自以为是
          重视自己,但不可目中无人

把二元查找树转变成排序的双向链表
题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
  比如将二元查找树
                                            10
                                          /    \
                                        6       14
                                      /  \     /  \
                                    4     8  12    16
转换成双向链表
4=6=8=10=12=14=16。

分析:这是一道关于二叉树和链表的算法题,据说也是一道微软面试题,见到树,大家一般都会第一时间想到用递归发解决,我们不妨就从这个方向进行考虑.
    将二叉查找树转换成链表,如果允许增加结点,就并不是一件很困难的事,因为我们可以发现,通过中序遍历,我们就可以得到一个排好序的数列.但是本题仅允许改变指针的指向,我们可以看到,二叉树每个结点本身已经有两个指针域,并且由于二叉查找树本身的性质,结点左边的值永远比该结点小,结点右边的值永远比该结点大,我们可以每次都假设一个结点的左右两端都是已经排序好的双链表,它左边的所有值一定比它小,它右边的所有值一定比它大,因此,修改这三个结点的指针指向就可以链接成一个排好序的链表.
解答代码:

 1typedef struct BSTree
 2{
 3    int data;
 4    BSTree *left;
 5    BSTree *right;
 6}
*myTree;
 7myTree Sort(myTree root,bool asright)
 8{
 9    myTree lNode,rNode,temp;
10    if(root == NULL)
11        return NULL;
12        //将左边的列表加到root结点的前端
13    if(root->left != NULL)
14    {
15        lNode = Sort(root->left,false);
16        root->left = lNode;
17        lNode->right = root;
18    }

19        //将右边的列表加到root结点的后端
20    if(root->right != NULL)
21    {
22        rNode = Sort(root->right,true);
23        root->right = rNode;
24        rNode->left = root;
25    }

26        //选择边界结点返回
27    if(!asright)//判断是否为右孩子
28    {
29        temp = root;
30        while(temp->right != NULL)
31            temp = temp->right;
32        return temp;
33    }

34    else if(asright)
35    {
36        temp = root;
37        while(temp->left != NULL)
38            temp = temp->left;
39        return temp;
40    }

41
42}

43int main(int argc, char* argv[])
44{
45    myTree root,lNode,rNode,temp;
46    root = CreateTree();//建立二叉查找树
47    lNode = Sort(root->left,false);
48    rNode = Sort(root->right,false);
49    root->left = lNode;
50    lNode->right = root;
51    root->right = rNode;
52    rNode->left = root;
53    temp = root;
54    while(temp->left != NULL)
55        temp = temp->left;
56    while(temp != NULL)
57    {
58        printf("%d ",temp->data);
59        temp = temp->right;
60
61    }

62    
63    return 0;
64}
    该代码为笔者所写,意在表达问题的解决思路,疏漏之处在所难免,请见谅,如果大家有什么问题,欢迎提出来共同讨论解决.
posted on 2007-08-14 09:04  幽儿  阅读(337)  评论(0编辑  收藏  举报