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

Posted 逆風的薔薇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将搜索二叉树转换成双向链表相关的知识,希望对你有一定的参考价值。

题目


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

分析

用两种方法求解本题。 方法一:由于是搜索二叉树,直接求出其中序遍历序列,构造双向链表即可。
方法二:采用递归实现。分别得到左右子树的双向子链表(保存该子链表的尾节点,并使该尾节点的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;


以上是关于将搜索二叉树转换成双向链表的主要内容,如果未能解决你的问题,请参考以下文章

二叉树转换成双向链表

二叉搜索树和双向链表

栈和队列----将搜索二叉树转换成双向链表

26二叉搜索树与双向链表

左神算法书籍《程序员代码面试指南》——2_12将搜索二叉树转换成双向链表

2021-06-02:给定一棵搜索二叉树头节点,转化成首尾相接的有序双向链表。