把二元查找树转变成排序的双向链表

题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,要求不能创建任何新节点,只调整指针指向。

比如将二元查找树

10

/       \

6        14

/  \        /     \

4   8   12   16

转换成双向链表4=6=8=10=12=14=16

分析:

思路一:当到达某一节点准备调整以该节点为根节点的子树时,先调整其左子树将左子树转换成一个排好序的左子链表,再调整其右子树转换右子链表。最近链接左子链表的最右节点(左子树的最大节点)、当前节点和有子链表的最左节点(右子树的最小节点)。从树的根节点开始递归调整所有节点。

首先定义二元查找树的数据结构如下:

structBSTreeNode

{

int m_nValue;

BSTreeNode *m_pLeft;

BSTreeNode *m_pRight;

}

  1. BSTreeNode*ConvertNode(BSTreeNode* pNode, bool asRight)
  2. {
  3. if (!pNode)
  4. returnNULL;
  5. BSTreeNode *pLeft = NULL;
  6. BSTreeNode* pRight = NULL;
  7.  
  8. //Convert the left sub-tree
  9. if(pNode -> m_pLeft)
  10. pLeft = ConvertNode(pNode ->m_pLeft, false);
  11.  
  12. //Convert the greatest node in the leftsub-tree to the current node
  13. if (pLeft)
  14. {
  15. pLeft -> m_pRight = pNode;
  16. pNode -> m_pLeft = pLeft;
  17. }
  18.  
  19. //Convert the right sub-tree
  20. if (pNode -> m_pRight)
  21. pRight= ConvertNode (pNode -> m_pRight, true);
  22.  
  23. //Connect the least node in the rightsub-tree to the current node
  24. if (pRight)
  25. {
  26. pNode-> m_pRight = pRight;
  27. pRight-> m_pLeft = pNode;
  28. }
  29.  
  30. BSTreeNode *pTemp = pNode;
  31.  
  32. //If the current node is the right child ofits parent, return the least node in the tree whose root is the current node
  33. if (asRight)
  34. {
  35. while(pTemp -> m_pLeft)
  36. pTemp= pTemp -> m_pLeft;
  37. }
  38. //if the current node is the left child ofits parent, return the greatest node in the tree whose root is the current node
  39. else
  40. {
  41. while(pTemp -> m_pRight)
  42. pTemp= pTemp -> m_pRight;
  43. }
  44. return pTemp;
  45.  
  46. //Convert a BSTree into a sorteddouble-linked list
  47. BSTreeNode* Convert(BSTreeNode* pHeadOfTree)
  48. {
  49. returnConvertNode(pHeadOfTree, true);
  50. }

思路二:中序遍历二叉树。较小节点先访问。如果访问一个节点,假设之前访问过的节点已经调整成一个排序的双向链表,再把调整当前节点的指针将其连接到链表末尾,当所有节点都访问过之后,整棵树也就转换为一个排序的双向链表了。

  1. voidConvertNode(BSTreeNode* pNode, BSTreeNode*& pLastNodeInList)
  2. {
  3. if(pNode ==NULL)
  4. return;
  5. BSTreeNode *pCurrent = pNode;
  6.  
  7. //Convert the left sub-tree
  8. if (pCurrent -> m_pLeft !=NULL)
  9. ConvertNode(pCurrent-> m_pLeft, pLastNodeInList);
  10.  
  11. //Put the current node into thedouble-linked list
  12. pCurrent -> m_pLeft = pLastNodeInList;
  13. if(pLastNodeInList != NULL)
  14. pLastNodeInList-> m_pRight = pCurrent;
  15.  
  16. pLastNodeInList = pCurrent;
  17.  
  18. //Convert the right sub-tree
  19. if (pCurrent -> m_pRight != NULL)
  20. ConvertNode(pCurrent-> m_pRight, pLastNodeInList);
  21.  
  22. //Convert a BSTree into a sorteddouble-linked list
  23. BSTreeNode* Convert_Solution(BSTreeNode*pHeadOfTree)
  24. {
  25. BSTreeNode*pLastNodeInList = NULL;
  26. ConvertNode(pHeadOfTree,pLastNodeInList);
  27.  
  28. //Getthe head of the double-linked list
  29. BSTreeNode*pHeadOfList = pLastNodeInList;
  30. while(pHeadOfList && pHeadOfList -> m_pLeft)
  31. pHeadOfList= pHeadOfList -> m_pLeft;
  32.  
  33. return pHeadOfList;
  34. }
  35. }

【Data structure & Algorithm】把二元查找树转变成排序的双向链表的更多相关文章

  1. MS - 1 - 把二元查找树转变成排序的双向链表

    ## 1. 把二元查找树转变成排序的双向链表 ## ### 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表. ### 要求不能创建任何新的结点,只调整指针的指向. 10       ...

  2. 二元查找树转变成排序的双向链表之C#算法实现

    此题为July在CSDN发布的微软编程面试100题中的第一题,觉得蛮有趣的,今天也拿过来玩玩,July的代码用的是C++实现,可能因为有指针的原因吧,感觉看起来相对比较容易理解整个的实现过程,而我,试 ...

  3. 1.把二元查找树转变成排序的双向链表[BST2DoubleLinkedList]

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

  4. IT公司100题-15-求二元查找树的镜像

    问题描述: 输入一颗二元查找树,将该树转换为它的镜像树,即对每一个节点,互换左右子树.   例如输入:   6/    \4     12/ \   /   \2  5 8   16 输出:   6/ ...

  5. IT公司100题-9-判断整数序列是不是二元查找树的后序遍历结果

    问题描述: 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果. 如果是返回true,否则返回false. 例如输入4, 8, 6, 12, 16, 14, 10,由于这一整数序列是如下树 ...

  6. 6.二元查找树的后序遍历结果[PostOrderOfBST]

    [题目] 输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果: 8 ...

  7. 11.求二元查找树的镜像[MirrorOfBST]

    [题目] 输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点.用递归和循环两种方法完成树的镜像转换. 例如输入: 8    /  \  6      1 ...

  8. [Data Structure & Algorithm] 七大查找算法

    查找是在大量的信息中寻找一个特定的信息元素,在计算机应用中,查找是常用的基本运算,例如编译程序中符号表的查找.本文简单概括性的介绍了常见的七种查找算法,说是七种,其实二分查找.插值查找以及斐波那契查找 ...

  9. [LeetCode] Add and Search Word - Data structure design 添加和查找单词-数据结构设计

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

随机推荐

  1. 随便写一点最近开发遇到的问题和解决方法 大部分关于laravel和php

    laravel里要想对对象进行自己设计的排序(usort()), 得用匿名方法,  原声php就不用 php里面可以随便写html代码,  比如可以把html直接后缀名改成.php, 然后在任何地方& ...

  2. svn 版本管理与自动部分发布(转)

    作为团队开发项目时,会遇到项目的版本管理,测试部署与发布部署,下面是摘至他人的关于版本管理和自动部署的方案. svn自动部署的实现: 使用svn的hook功能 1.在版本库的hooks目录下面,有一些 ...

  3. Node.js 笔记(一) nodejs、npm、express安装(转)

    转载地址:http://blog.csdn.net/haidaochen/article/details/7257655 Windows平台下的node.js安装 直接去nodejs的官网http:/ ...

  4. Matlab---傅里叶变换---通俗理解(二)

    1.用Matlab进行傅立叶变换 FFT是离散傅里叶变换的高速算法,能够将一个信号变换到频域.有些信号在时域上是非常难看出什么特征的,可是假设变换到频域之后,就非常easy看出特征了.这就是非常多信号 ...

  5. 在fedora25x86下编译opencv的Android版本的过程记录

    准备材料: 1. 32位的Fedora25(不建议使用64位系统----64位系统下也是可以编译的,这里为了简单起见,考虑使用32位操作系统.事实上,本人在64位操作系统下也做了尝试,也完成了编译.) ...

  6. ORACLE SQL性能优化(全)

    ORACLE SQL性能优化(全) http://wenku.baidu.com/view/b2aaba3887c24028915fc337.html

  7. 基于EasyDarwin实现幼儿园监控类项目

    移动互联网越来越普及,幼儿园监控类的项目也越来越多,如何能够以最低的成本.最快的速度搭建一套幼儿园监控类的平台成了许多开发者的需求,那么我们今天就来简单探讨一下如何基于EasyDarwin实现一套幼儿 ...

  8. UVA 10951 - Polynomial GCD(数论)

    UVA 10951 - Polynomial GCD 题目链接 题意:给定两个多项式,求多项式的gcd,要求首项次数为1,多项式中的运算都%n,而且n为素数. 思路:和gcd基本一样,仅仅只是传入的是 ...

  9. js 单例模式的实现方式----闭包和构造函数内部判断

    闭包: var singleton = function( fn ){ var result; return function(){ return result || ( result = fn .a ...

  10. CoreGraphics(转)

    2.CoreGraphics 上面我们讲过,UIBezierPath是CoreGraphics的封装,使用它可以完成大部分的绘图操作,不过更底层的CoreGraphics更加强大. CoreGraph ...