1、把二元查找树转变成排序的双向链表

1. 把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};

 

思路:二元查找树的规律是做子树的所有节点小于根节点,右子树的所有节点大于根节点,可以推断出转成双向链表后,根节点的前一个节点为左子树的最大值,即左子树最右边的节点,根节点的后一个节点为右子树的最小值,即右子树最左边的节点。

利用树的递归的性质,每个非叶子节点都可以找到前节点和后节点。对于叶子节点,他的前节点 和 后节点肯定都不是叶子节点,所以可以用下面的伪代码来实现

void tranferToDoubleLinkedList(BSTreeNode *tree)

{
	if (tree->m_pLeft)
	{
		BSTreeNode *node = getMaxElement(tree->m_pLeft);

		tranferToDoubleLinkedList(tree->m_pLeft);

		tree->m_pLeft = node;
		node->m_pRight = tree;
	}

	if (tree->m_pRight)
	{
		BSTreeNode *node = getMinElement(tree->m_pRight);

		tranferToDoubleLinkedList(tree->m_pRight);

		tree->m_pRight = node;
		node->m_pLeft = tree;
	}
}


下面是完整的源码:

 

/*
1.把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
*/

#ifndef INTERVIEW_1_H
#define INTERVIEW_1_H

class BSTreeNode
{
public:
	int m_nValue;
	BSTreeNode *m_pLeft;	// mapped to pre node when transferring to Double Liked List
	BSTreeNode *m_pRight;	// mapped to next node when transferring to Double Liked List
};

class BSTree
{
public:
	BSTree(BSTreeNode *node)
	{
		root = node;
	}

	BSTreeNode* GetMaxElement() const;
	BSTreeNode* GetMinElement() const;
	void GenerateDoubleLikedList();

private:
	BSTreeNode *root;
};

#endif //INTERVIEW_1_H


 

#include "Interview_1.h"
#include <iostream>

using namespace std;

BSTreeNode* BSTree::GetMaxElement() const
{
	if (root == NULL)
		return NULL;
	BSTreeNode* max = root;

	while(max->m_pRight)
	{
		max = max->m_pRight;
	}
	return max;
}

BSTreeNode* BSTree::GetMinElement() const
{
	if (root == NULL)
	{
		return NULL;
	}

	BSTreeNode *min = root;
	while(min->m_pLeft)
	{
		min = min->m_pLeft;
	}

	return min;
}

void BSTree::GenerateDoubleLikedList()
{
	if (root->m_pLeft != NULL)
	{
		BSTree leftTree(root->m_pLeft);
		BSTreeNode *pre = leftTree.GetMaxElement();
		root->m_pLeft = pre;

		leftTree.GenerateDoubleLikedList();
		pre->m_pRight = root;
	}
	
	if (root->m_pRight != NULL)
	{
		BSTree rightTree(root->m_pRight);
		BSTreeNode *next = rightTree.GetMinElement();
		root->m_pRight = next;
		rightTree.GenerateDoubleLikedList();
		next->m_pLeft = root;
	}
}


 

 

//原题目地址: http://topic.csdn.net/u/20101126/10/b4f12a00-6280-492f-b785-cb6835a63dc9.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值