简述:
二叉排序树在不改变BinaryNode<Type>的 struct{data;*left;*right} 情况下是可以转换成双向链表的.
由于二叉树的主要数据都记录在根节点BinaryNode<Type>* root 上的,所以这里就只用BinaryNode类手动建一棵树,
树形如下:
新增的有三个主要函数,
BinaryNode<Type>* GetHead() 是用来查找右子树最小的那个节点
BinaryNode<Type>* GetTail() 是用来查找左子树最大的那个节点
void convert()是转换函数,递归调用
上述两个节点找到之后,分别连上根节点
如图所示:L:left R:right
这里必须注意的是这里使用了递归修改,所以一定要先进行子节点修改的时候,回溯的时候再修改父节点,不然如果父节点的时候修改了树的结构,那么子节点处理的时候就会出错。我用了recordHead,recordTail来记录当前处理的节点左右子树的尾节点和首节点
下面是BinaryNode<Type>类,及GetHead() GetTail() 和convert的
实现:
/***********************二叉树转换成双向链表*********************/
#include <iostream>
using namespace std;
/*1.二叉节点其实包含了关于树的大部分数据结构算法,因为二叉树本身的性质也是体现在那
* 个根节点BinaryNdoe<Type> *root上所以很多算法比如遍历、递归复制、算高度、算节点
* 数都是异曲同工的
*/
/*2.实现二叉节点,他的赋值、遍历及其他算法都与多叉节点相似,只要增加left、right之外
* 的指针就能达到多叉节点的效果
*/
/**********************************二叉节点**********************************/
template<class Type>
struct BinaryNode{
//private:
Type data;
BinaryNode<Type> *left;
BinaryNode<Type> *right;
public:
BinaryNode(): left(NULL),right(NULL){}
BinaryNode(const Type& value): data(value),left(NULL),right(NULL){}
/****************************将二叉数转换成链表*****************************/
//找到右子树的Head
BinaryNode<Type>* GetHead(){
BinaryNode<Type> *head = this;
while(true){
if(head->left != NULL)
head = head->left;
else
break;
}
return head;
}
//找到左子树的Tail
BinaryNode<Type>* GetTail(){
BinaryNode<Type> *tail = this;
while(true){
if(tail->right != NULL)
tail = tail->right;
else
break;
}
return tail;
}
void convert(){
//左右子树递归转换,必须自叶子向根,不然会出错
if(left != NULL){
//记录根节点的指向右子树的得到右子树的head
BinaryNode<Type> *recordTail = left->GetTail();
left->convert();
recordTail->right = this;
left = recordTail;
}
if(right != NULL){
//记录根节点的指向左子树得到左子树的tail
BinaryNode<Type> *recordHead = right->GetHead();
right->convert();
recordHead->left = this;
right = recordHead;
}
}
/**********************************************************************/
};
测试函数:
其中 p7 是根.
int main(){
/*******************************建树************************************/
BinaryNode<int> *p7 = new BinaryNode<int>(7);
BinaryNode<int> *p4 = new BinaryNode<int>(4);
BinaryNode<int> *p10 = new BinaryNode<int>(10);
BinaryNode<int> *p1 = new BinaryNode<int>(1);
BinaryNode<int> *p5 = new BinaryNode<int>(5);
BinaryNode<int> *p9 = new BinaryNode<int>(9);
BinaryNode<int> *p13 = new BinaryNode<int>(13);
BinaryNode<int> *p0 = new BinaryNode<int>(0);
BinaryNode<int> *p2 = new BinaryNode<int>(2);
BinaryNode<int> *p12 = new BinaryNode<int>(12);
BinaryNode<int> *p14 = new BinaryNode<int>(14);
BinaryNode<int> *p11 = new BinaryNode<int>(11);
p7->left = p4; p7->right = p10;
p4->left = p1; p4->right = p5;
p10->left = p9; p10->right = p13;
p1->left = p0; p1->right = p2;
p13->left = p12; p13->right = p14;
p12->left = p11;
/***********************************************************************/
//以根节点转换该树
p7->convert();
//连接首尾
p0->left = p14;
p14->right = p0;
//向右输出
cout << "向右输出:" << endl;
BinaryNode<int> *curNode = p0;
for(int i = 1;i <= 30;i++){
cout << curNode->data << " ";
curNode = curNode->right;
if(i % 12 == 0)
cout << endl;
}
cout << "\n\n";
//向左输出
cout << "向左输出:" << endl;
curNode = p14;
for(int i = 1;i <= 30;i++){
cout << curNode->data << " ";
curNode = curNode->left;
if(i % 12 == 0)
cout << endl;
}
return 0;
}
测试输出: