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

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值