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

Posted kevin55

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MS - 把二元查找树转变成排序的双向链表相关的知识,希望对你有一定的参考价值。

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

        10
       /   \
      6     14
     /  \  /  \
    4   8 12  16 
转换成双向链表 4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下: 

1 struct BSTreeNode 
2     {
3         int m_nValue; // value of node 
4         BSTreeNode *m_pLeft; // left child of node 
5         BSTreeNode *m_pRight; // right child of node 
6     };

下面是使用C++泛型写的一种算法:

  1 #include "stdafx.h"
  2 #include <string>
  3 #include <iostream>
  4 using namespace std;
  5 
  6 template<typename T>
  7 struct BSTTreeNode
  8 {
  9     BSTTreeNode(T v, BSTTreeNode* lNode = NULL, BSTTreeNode* rNode=NULL) 
 10         :m_Value(v), m_pLeft(lNode), m_pRight(rNode){}
 11     T m_Value;
 12     BSTTreeNode* m_pLeft;
 13     BSTTreeNode* m_pRight;
 14 };
 15 
 16 
 17 template<typename T>
 18 void TravelBSTree(BSTTreeNode<T> *root)
 19 {
 20     if (NULL == root)
 21     {
 22         return;
 23     }
 24 
 25     TravelBSTree(root->m_pLeft);
 26 
 27     printf("%d ", root->m_Value);
 28     
 29     TravelBSTree(root->m_pRight);
 30     
 31 }
 32 
 33 template<typename T>
 34 void TravelBSTreeAsList(BSTTreeNode<T> *head, bool bReverseTravel = false)
 35 {
 36     BSTTreeNode<T>* pNode = head;
 37     while (pNode)
 38     {
 39         printf("%d ", pNode->m_Value);
 40         if (!bReverseTravel)
 41         {
 42             pNode = pNode->m_pRight;
 43         }
 44         else
 45         {
 46             pNode = pNode->m_pLeft;
 47         }
 48     }
 49 }
 50 
 51 //思路:
 52 //查找树,中序遍历得到的节点排序即为排序的链表,而要求排序的双向链表,
 53 //1. 假设lt为左子树的中序遍历的尾结点,rh为右子树中序遍历的头结点
 54 //2. 化繁为简,如果只有root, lt, rh三个节点,此时只须然这几个节点连接起来即可。
 55 //3. 分别遍历左右子树,重复上述过程。
 56 template<typename T>
 57 void BSTreeHelper(BSTTreeNode<T>* &head, BSTTreeNode<T>* &tail, BSTTreeNode<T>* root)
 58 {
 59     //step 1.
 60     BSTTreeNode<T>* lt = NULL;//左子树尾结点
 61     BSTTreeNode<T>* rh = NULL;//右子树头结点
 62 
 63     if (NULL == root)
 64     {
 65         head = nullptr;
 66         tail = nullptr;
 67         return;
 68     }
 69 
 70     //step 3.
 71     BSTreeHelper(head, lt, root->m_pLeft);
 72     BSTreeHelper(rh, tail, root->m_pRight);
 73 
 74     //step 2.
 75     if (NULL != lt)
 76     {
 77         lt->m_pRight = root;
 78         root->m_pLeft = lt;
 79     }
 80     else
 81     {
 82         head = root;
 83     }
 84 
 85     if (NULL != rh)
 86     {
 87         root->m_pRight = rh;
 88         rh->m_pLeft = root;
 89     }
 90     else
 91     {
 92         tail = root;
 93     }
 94 }
 95 
 96 template<typename T>
 97 BSTTreeNode<T>* TreeToLinkedList(BSTTreeNode<T>* root)
 98 {
 99     BSTTreeNode<T>* head = NULL;
100     BSTTreeNode<T>* tail = NULL;
101 
102     BSTreeHelper(head, tail, root);
103 
104     return head;
105 }
106 
107 int _tmain(int argc, _TCHAR* argv[])
108 {
109     int arr[] = {4, 6, 8, 10, 12, 14, 16};
110 
111     BSTTreeNode<int> node4(4);
112     BSTTreeNode<int> node8(8);
113     BSTTreeNode<int> node6(6, &node4, &node8);
114     BSTTreeNode<int> node12(12);
115     BSTTreeNode<int> node16(16);
116     BSTTreeNode<int> node14(14, &node12, &node16);
117     BSTTreeNode<int> node10(10, &node6, &node14);
118     BSTTreeNode<int>* pRoot = &node10;
119 
120     printf("Travel BSTree: \n");
121     TravelBSTree<int>(pRoot);
122     printf("\n");
123 
124     TreeToLinkedList<int>(pRoot);
125 
126     printf("Travel BSTree: \n");
127     TravelBSTreeAsList<int>(&node4, false);
128     printf("\n");
129     
130     TravelBSTreeAsList<int>(&node16, true);
131     printf("\n");
132 
133     return 0;
134 }

 

以上是关于MS - 把二元查找树转变成排序的双向链表的主要内容,如果未能解决你的问题,请参考以下文章

算法1

.net 面试题

将二叉搜索树转变成排序的双向链表

数据结构与算法面试题80道

数据结构——树——二叉查找树转换成排序的循环双向链表

26二叉搜索树与双向链表