参见博客:
http://zhedahht.blog.163.com/blog/static/254111742007127104759245/
http://www.cnblogs.com/caidaxia/archive/2011/10/14/2212369.html
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
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
};
思路一的代码为:
///////////////////////////////////////////////////////////////////////
// Covert a sub binary-search-tree into a sorted double-linked list
// Input: pNode - the head of the sub tree
// asRight - whether pNode is the right child of its parent
// Output: if asRight is true, return the least node in the sub-tree
// else return the greatest node in the sub-tree
///////////////////////////////////////////////////////////////////////
BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight)
{
if(!pNode)
return NULL;
BSTreeNode *pLeft = NULL;
BSTreeNode *pRight = NULL;
// Convert the left sub-tree
if(pNode->m_pLeft)
pLeft = ConvertNode(pNode->m_pLeft, false);
// Connect the greatest node in the left sub-tree to the current node
if(pLeft)
{
pLeft->m_pRight = pNode;
pNode->m_pLeft = pLeft;
}
// Convert the right sub-tree
if(pNode->m_pRight)
pRight = ConvertNode(pNode->m_pRight, true);
// Connect the least node in the right sub-tree to the current node
if(pRight)
{
pNode->m_pRight = pRight;
pRight->m_pLeft = pNode;
}
BSTreeNode *pTemp = pNode;
// If the current node is the right child of its parent,
// return the least node in the tree whose root is the current node
if(asRight)
{
while(pTemp->m_pLeft)
pTemp = pTemp->m_pLeft;
}
// If the current node is the left child of its parent,
// return the greatest node in the tree whose root is the current node
else
{
while(pTemp->m_pRight)
pTemp = pTemp->m_pRight;
}
return pTemp;
}
///////////////////////////////////////////////////////////////////////
// Covert a binary search tree into a sorted double-linked list
// Input: the head of tree
// Output: the head of sorted double-linked list
///////////////////////////////////////////////////////////////////////
BSTreeNode* Convert(BSTreeNode* pHeadOfTree)
{
// As we want to return the head of the sorted double-linked list,
// we set the second parameter to be true
return ConvertNode(pHeadOfTree, true);
}
下面给出思路二的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// 1:构造二叉查找树;
// 2:中序遍历二叉查找树,因此结点按从小到大顺序访问,假设之前访问过的结点已经调整为一个双向链表,那么
// 只需要将当前结点连接至双向链表的最后一个结点即可,访问完后,双向链表也就调整完了
#include <iostream>
using
namespace
std;
struct
BSTreeNode
{
int
m_nValue;
// value of node
BSTreeNode *m_pLeft;
// left child of node
BSTreeNode *m_pRight;
// right child of node
};
void
addBSTreeNode(BSTreeNode *&pCurrent,
int
value);
void
inOrderBSTree(BSTreeNode* pBSTree);
void
convertToDoubleList(BSTreeNode* pCurrent);
BSTreeNode *pHead=NULL;
//指向循环队列头结点
BSTreeNode *pIndex=NULL;
//指向前一个结点
int
main()
{
BSTreeNode *pRoot=NULL;
addBSTreeNode(pRoot,10);
addBSTreeNode(pRoot,6);
addBSTreeNode(pRoot,14);
addBSTreeNode(pRoot,4);
addBSTreeNode(pRoot,8);
addBSTreeNode(pRoot,12);
addBSTreeNode(pRoot,16);
inOrderBSTree(pRoot);
return
0;
}
/************************************************************************/
/* 建立二叉排序树 */
void
addBSTreeNode(BSTreeNode *&pCurrent,
int
value)
//在这个函数中会要改变指针值,一定要记得使用引用传递
{
if
(pCurrent==NULL)
{
BSTreeNode* pBSTree=
new
BSTreeNode();
pBSTree->m_nValue=value;
pBSTree->m_pLeft=NULL;
pBSTree->m_pRight=NULL;
pCurrent=pBSTree;
}
else
if
(pCurrent->m_nValue<value)
{
addBSTreeNode(pCurrent->m_pRight,value);
}
else
if
(pCurrent->m_nValue>value)
{
addBSTreeNode(pCurrent->m_pLeft,value);
}
else
{
cout<<
"node repeated"
<<endl;
}
}
/************************************************************************/
/************************************************************************/
/* 中序遍历二叉树,同时调整结点指针 */
void
inOrderBSTree(BSTreeNode* pBSTree)
{
if
(NULL==pBSTree)
{
return
;
}
if
(NULL!=pBSTree->m_pLeft)
{
inOrderBSTree(pBSTree->m_pLeft);
}
// if (NULL!=pBSTree)
// {
// cout<<pBSTree->m_nValue;
// }
convertToDoubleList(pBSTree);
if
(NULL!=pBSTree->m_pRight)
{
inOrderBSTree(pBSTree->m_pRight);
}
}
/************************************************************************/
/************************************************************************/
/* 调整结点指针 */
void
convertToDoubleList(BSTreeNode* pCurrent)
{
pCurrent->m_pLeft=pIndex;
//使当前结点的左指针指向双向链表中最后一个结点
if
(NULL==pIndex)
//若最后一个元素不存在,此时双向链表尚未建立,因此将当前结点设为双向链表头结点
{
pHead=pCurrent;
}
else
//使双向链表中最后一个结点的右指针指向当前结点
{
pIndex->m_pRight=pCurrent;
}
pIndex=pCurrent;
//将当前结点设为双向链表中最后一个结点
cout<<pCurrent->m_nValue<<
" "
;
}
/******************************************************************
|