算法小趣(一)

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

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

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

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

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

34InBlock.gif    else if(asright)
35ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
36InBlock.gif        temp = root;
37InBlock.gif        while(temp->left != NULL)
38InBlock.gif            temp = temp->left;
39InBlock.gif        return temp;
40ExpandedSubBlockEnd.gif    }

41InBlock.gif
42ExpandedBlockEnd.gif}

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

62InBlock.gif    
63InBlock.gif    return 0;
64ExpandedBlockEnd.gif}
    该代码为笔者所写,意在表达问题的解决思路,疏漏之处在所难免,请见谅,如果大家有什么问题,欢迎提出来共同讨论解决.

转载于:https://www.cnblogs.com/lingling8420/archive/2007/08/14/854692.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值