【编程题目】把二元查找树转变成排序的双向链表(树)

1.把二元查找树转变成排序的双向链表(树)
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};

 

 

我的思路:找到最小元素做头结点,不断的找其后继,调整指针的指向。写了一个半小时!

  1 /*

  2 1.把二元查找树转变成排序的双向链表(树)

  3 题目:

  4 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

  5 要求不能创建任何新的结点,只调整指针的指向。

  6      10

  7     / \

  8    6   14

  9   / \  / \

 10   4 8 12 16

 11 转换成双向链表

 12 4=6=8=10=12=14=16。

 13 首先我们定义的二元查找树  节点的数据结构如下:

 14 struct BSTreeNode

 15 {

 16 int m_nValue; // value of node

 17 BSTreeNode *m_pLeft; // left child of node

 18 BSTreeNode *m_pRight; // right child of node

 19 };

 20 start time = 14:31

 21 end time = 16:04

 22 */

 23 #include <iostream>

 24 #include <stdlib.h>

 25 using namespace std;

 26 

 27 typedef struct BSTreeNode

 28 {

 29 int m_nValue; // value of node

 30 BSTreeNode *m_pLeft; // left child of node

 31 BSTreeNode *m_pRight; // right child of node

 32 }BSTreeNode;

 33 

 34 int addBSTreeNode(BSTreeNode * &T, int data)  //把data加入的以T为根的树中

 35 {

 36     if(T == NULL) //根节点单独处理

 37     {

 38         T = (BSTreeNode *)malloc(sizeof(BSTreeNode));

 39         T->m_nValue = data;

 40         T->m_pLeft = NULL;

 41         T->m_pRight = NULL;

 42     }

 43     else

 44     {

 45         BSTreeNode * x = T;

 46         BSTreeNode * px = NULL;

 47         while(x != NULL)

 48         {

 49             if(data >= x->m_nValue)

 50             {

 51                 px = x;

 52                 x = x->m_pRight;

 53             }

 54             else

 55             {

 56                 px = x;

 57                 x = x->m_pLeft;

 58             }

 59         }

 60 

 61         if(data >= px->m_nValue)

 62         {

 63             px->m_pRight = (BSTreeNode *)malloc(sizeof(BSTreeNode));

 64             px->m_pRight->m_nValue = data;

 65             px->m_pRight->m_pLeft = NULL;

 66             px->m_pRight->m_pRight = NULL;

 67         }

 68         else

 69         {

 70             px->m_pLeft = (BSTreeNode *)malloc(sizeof(BSTreeNode));

 71             px->m_pLeft->m_nValue = data;

 72             px->m_pLeft->m_pLeft = NULL;

 73             px->m_pLeft->m_pRight = NULL;

 74         }

 75     }

 76     return 1;

 77 }

 78 

 79 BSTreeNode * findMin(BSTreeNode * z)

 80 {

 81     BSTreeNode * x = z;

 82     while(x->m_pLeft != NULL)

 83     {

 84         x = x->m_pLeft;

 85     }

 86     return x;

 87 }

 88 

 89 BSTreeNode * findMax(BSTreeNode * z)

 90 {

 91     BSTreeNode * x = z;

 92     while(x->m_pRight != NULL)

 93     {

 94         x = x->m_pRight;

 95     }

 96     return x;

 97 }

 98 

 99 BSTreeNode * findparent(BSTreeNode * T,BSTreeNode * z)

100 {

101     BSTreeNode * x = T;

102     BSTreeNode * px = NULL;

103     while(x != NULL)

104     {

105         if(z->m_nValue > x->m_nValue)

106         {

107             px = x;

108             x = x->m_pRight;

109         }

110         else if(z->m_nValue < x->m_nValue)

111         {

112             px = x;

113             x = x->m_pLeft;

114         }

115         else

116         {

117             if(z == x) //对数值相同的情况做判断 

118             {

119                 return px;

120             }

121             else

122             {

123                 px = x;

124                 x = x->m_pRight;

125             }

126         }

127     }

128     return NULL;

129 }

130 

131 BSTreeNode * BSTreefindSuccessor(BSTreeNode * T, BSTreeNode * z) //找二元查找树某个节点的后继

132 {

133     if(z->m_pRight != NULL)

134     {

135         return  findMin(z->m_pRight);

136     }

137     else

138     {

139         BSTreeNode * y = findparent(T, z);

140         while(y != NULL && z == y->m_pRight)

141         {

142             z = y;

143             y = findparent(T, z);

144         }

145         return y;

146     }

147 }

148 

149 BSTreeNode * BSTree2OrderedList(BSTreeNode * T) //把二元查找树转换为排序的双向链表

150 {

151     BSTreeNode * start = findMin(T);

152     BSTreeNode * end = findMax(T);

153     BSTreeNode * x = start;

154     BSTreeNode * root = T;

155     while(x != NULL)

156     {

157         BSTreeNode * xs = BSTreefindSuccessor(root, x);

158         if(xs == root && root != NULL) //当root 左右子树的指向改变的时候 要更新找后继的树根 否则根的右子树变化了 用找后继会出错

159         {

160             root = root->m_pRight;

161         }

162         if(xs != NULL)

163         {

164             x->m_pRight = xs;  //向右指向下一个比它大的值

165             xs->m_pLeft = x;   //向左指向下一个比它小的值

166         }

167         x = xs;

168     }

169     return start;

170 }

171 

172 

173 int main()

174 {

175     BSTreeNode * T = NULL;

176     addBSTreeNode(T, 10);

177     addBSTreeNode(T, 6);

178     addBSTreeNode(T, 6);

179     addBSTreeNode(T, 4);

180     addBSTreeNode(T, 8);

181     addBSTreeNode(T, 12);

182     addBSTreeNode(T, 16);

183 

184     BSTreeNode * ans = BSTree2OrderedList(T);

185 

186     return 0;

187 

188 }
View Code

 

之后上网看看别人的 结果人家一个中序遍历就搞定了啊!

来源:http://blog.csdn.net/wcyoot/article/details/6428297

 1 template<typename T>

 2 struct TreeNode

 3 {

 4     T data;

 5     TreeNode* pLChild;

 6     TreeNode* pRChild;

 7 };

 8 

 9 // 要求两个输出参数要初始化为NULL

10 template<typename T>

11 void ConvertBSTree2List(TreeNode<T>* pTreeRoot/*树的根节点*/, TreeNode<T>*& pListHead/*双向链表的头指针*/, TreeNode<T>*& pListLast/*双向链表的尾指针*/)

12 {

13     if(pTreeRoot == NULL)

14     {

15         return;

16     }

17 

18     // 中序遍历左子树

19     ConvertBSTree2List(pTreeRoot->pLChild, pListHead, pListLast);

20 

21     // 处理当前节点,把节点链到双向链表尾部

22 

23     // 修改当前节点左指针,指向双向链表尾部

24     pTreeRoot->pLChild = pListLast;

25     if(pListLast)        // 非第一个节点

26     {

27         pListLast->pRChild = pTreeRoot;

28     }

29     else                // 第一个节点

30     {

31         pListHead = pTreeRoot;    

32     }

33 

34     pListLast = pTreeRoot;

35 

36     // 中序遍历右子树

37     ConvertBSTree2List(pTreeRoot->pRChild, pListHead, pListLast);

38 }
View Code

 

你可能感兴趣的:(双向链表)