将搜索二叉树转换成双向链表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fly_yr/article/details/52400766

题目


对二叉树的节点来说, 有本身的值域, 有指向左孩子和右孩子的两个指针; 对双向链表的节点来说,有本身的值域, 有指向上一个节点和下一个节点的指针。 在结构上, 两种结构有相似性, 现在有一棵搜索二叉树, 请将其转换为一个有序的双向链表。

分析

用两种方法求解本题。
方法一:由于是搜索二叉树,直接求出其中序遍历序列,构造双向链表即可。

方法二:采用递归实现。分别得到左右子树的双向子链表(保存该子链表的尾节点,并使该尾节点的next链接子链表的头节点,性能优化,避免线性查找),然后将当前节点链接即可。

代码

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

//双向链表结构体
struct DListNode {
	int val;
	DListNode *prev, *next;
	DListNode(int v) :val(v), prev(NULL),next(NULL){}
};

//二叉搜索树
struct BSTNode {
	int val;
	BSTNode *left, *right;
	BSTNode(int v):val(v),left(NULL),right(NULL){}
};

//二叉搜索树插入节点
void insert(BSTNode **root, int val)
{
	if (*root == NULL)
	{
		*root = new BSTNode(val);
		return;
	}

	if (val < (*root)->val)
		insert(&((*root)->left),val);
	else
		insert(&((*root)->right),val);
}

//中序遍历二叉树
void inOrder(BSTNode *root, vector<int> &ret)
{
	if (root == NULL)
		return;
	inOrder(root->left, ret);
	ret.push_back(root->val);
	inOrder(root->right, ret);
}

//方法一,利用中序排序得到二叉搜索树序列,构造双向链表T(n)=o(n) S(n)=o(n)
DListNode *translate(BSTNode *root)
{
	if (root == NULL)
		return NULL;

	vector<int> inRet;
	inOrder(root, inRet);

	DListNode *head = NULL, *p = NULL;
	for (auto iter = inRet.begin(); iter != inRet.end(); ++iter)
	{
		if (head == NULL)
		{
			head = new DListNode(*iter);
			p = head;
		}//if
		else {
			DListNode *node = new DListNode(*iter);
			node->prev = p;
			p->next = node;

			p = node;
		}//else
	}//for
	return head;
}

//方法二,递归实现,T(n)=O(n) S(n)=O(h)
DListNode *translate2(BSTNode *root)
{
	if (root == NULL)
		return NULL;

	//返回构造好链表的尾节点,并使得尾节点的next指向头结点
	DListNode *lEnd = translate2(root->left);
	DListNode *rEnd = translate2(root->right);

	DListNode *lHead = NULL;
	DListNode *rHead = NULL;
	if (lEnd)
		lHead = lEnd->next;
	if (rEnd)
		rHead = rEnd->next;

	DListNode *node = new DListNode(root->val);
	if (lEnd && rEnd)
	{
		lEnd->next = node;
		node->prev = lEnd;
		node->next = rHead;
		rHead->prev = node;

		rEnd->next = lHead;
	}//if
	else if (lEnd != NULL)
	{
		lEnd->next = node;
		node->prev = lEnd;

		node->next = lHead;
		return node;
	}
	else if (rEnd != NULL)
	{
		node->next = rHead;
		rHead->prev = node;

		rEnd->next = node;
		
		return rEnd;
	}else{
		node->next = node;
		return node;
	}
}

//遍历双向链表
void display(DListNode *head)
{
	if (head == NULL)
		return;

	DListNode *p = head;
	while (p)
	{
		cout << p->val << "\t";
		p = p->next;
	}//while

	cout << endl;
}

int main()
{
	vector<int> v = { 5,4,6,2,7 };
	BSTNode *root = NULL;

	for (auto iter = v.begin(); iter != v.end(); ++iter)
	{
		insert(&root, *iter);
	}//for

	DListNode *head = translate(root);

	display(head);

	DListNode *end = translate2(root);
	head = end->next;
	end->next = NULL;
	display(head);

	system("pause");
	return 0;
}


猜你喜欢

转载自blog.csdn.net/fly_yr/article/details/52400766