题目:
把二元查找树转变成排序的双向链表
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
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
};
思路:
递归
先把左子树和右子树转化为链表,然后把左子树的尾部跟父结点跟右字树连接起来形成一个新链表,进行递归即可。记录的头部结点与尾部结点需要用引用形参。
C++代码实现:
#include <iostream>
using namespace std;
struct BSTreeNode{
int m_nValue;
BSTreeNode *m_pleft;
BSTreeNode *m_pright;
};
void addBSTreeNode(BSTreeNode *&pCurrent, int value);
void inOrderBSTreePrint(BSTreeNode *pRoot);
void helpToBeLink(BSTreeNode *&head, BSTreeNode *&tail, BSTreeNode *root);
BSTreeNode* toBeLink(BSTreeNode *pRoot){
BSTreeNode* head = NULL;
BSTreeNode* tail = NULL;
helpToBeLink(head, tail, pRoot);
return head;
}
void inOrderBSTreePrint(BSTreeNode *pRoot);
void helpToBeLink(BSTreeNode *&head, BSTreeNode *&tail, BSTreeNode *root);
BSTreeNode* toBeLink(BSTreeNode *pRoot){
BSTreeNode* head = NULL;
BSTreeNode* tail = NULL;
helpToBeLink(head, tail, pRoot);
return head;
}
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);
inOrderBSTreePrint(pRoot);
cout << endl;
BSTreeNode* head = toBeLink(pRoot);
BSTreeNode* temp = head;
while (temp != NULL){
cout << temp->m_nValue << " ";
temp = temp->m_pright;
}
}
BSTreeNode *pRoot = NULL;
addBSTreeNode(pRoot, 10);
addBSTreeNode(pRoot, 6);
addBSTreeNode(pRoot, 14);
addBSTreeNode(pRoot, 4);
addBSTreeNode(pRoot, 8);
addBSTreeNode(pRoot, 12);
addBSTreeNode(pRoot, 16);
inOrderBSTreePrint(pRoot);
cout << endl;
BSTreeNode* head = toBeLink(pRoot);
BSTreeNode* temp = head;
while (temp != NULL){
cout << temp->m_nValue << " ";
temp = temp->m_pright;
}
}
void helpToBeLink(BSTreeNode *&head, BSTreeNode *&tail, BSTreeNode *root){
BSTreeNode *lt, *rh;
if (root == NULL){
head = NULL;
tail = NULL;
return;
}
helpToBeLink(head, lt, root->m_pleft);
helpToBeLink(rh, tail, root->m_pright);
if (lt != NULL){
lt->m_pright = root;
root->m_pleft = lt;
}
else{
head = root;
}
if (rh != NULL){
rh->m_pleft = root;
root->m_pright = rh;
}
else{
tail = root;
}
}
BSTreeNode *lt, *rh;
if (root == NULL){
head = NULL;
tail = NULL;
return;
}
helpToBeLink(head, lt, root->m_pleft);
helpToBeLink(rh, tail, root->m_pright);
if (lt != NULL){
lt->m_pright = root;
root->m_pleft = lt;
}
else{
head = root;
}
if (rh != NULL){
rh->m_pleft = root;
root->m_pright = rh;
}
else{
tail = root;
}
}
void addBSTreeNode(BSTreeNode *&pCurrent, int value){
if (pCurrent == NULL){
pCurrent = new BSTreeNode();
pCurrent->m_nValue = value;
pCurrent->m_pleft = NULL;
pCurrent->m_pright = NULL;
}
else if (pCurrent->m_nValue > value){
addBSTreeNode(pCurrent->m_pleft, value);
}
else if (pCurrent->m_nValue < value){
addBSTreeNode(pCurrent->m_pright, value);
}
else{
cout << "Node repeated" << endl;
}
}
void inOrderBSTreePrint(BSTreeNode *pRoot){
if (pRoot != NULL){
inOrderBSTreePrint(pRoot->m_pleft);
cout << pRoot->m_nValue << " ";
inOrderBSTreePrint(pRoot->m_pright);
if (pCurrent == NULL){
pCurrent = new BSTreeNode();
pCurrent->m_nValue = value;
pCurrent->m_pleft = NULL;
pCurrent->m_pright = NULL;
}
else if (pCurrent->m_nValue > value){
addBSTreeNode(pCurrent->m_pleft, value);
}
else if (pCurrent->m_nValue < value){
addBSTreeNode(pCurrent->m_pright, value);
}
else{
cout << "Node repeated" << endl;
}
}
void inOrderBSTreePrint(BSTreeNode *pRoot){
if (pRoot != NULL){
inOrderBSTreePrint(pRoot->m_pleft);
cout << pRoot->m_nValue << " ";
inOrderBSTreePrint(pRoot->m_pright);
}
}
}