二叉树转换成双向链表

简述:

二叉排序树在不改变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;
}

测试输出:

《二叉树转换成双向链表》

    原文作者:anialy
    原文地址: https://blog.csdn.net/anialy/article/details/7645535
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞