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