微软算法面试(1):把二元查找树转变成排序的双向链表(树)

题目:

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

要求不能创建任何新的结点,只调整指针的指向。

10

/ /

6 14

/ / / /

4 8 12 16

转换成双向链表

4=6=8=10=12=14=16。

实现如下:

#include<iostream>

using namespace std;

//定义二元查找树
struct BSTreeNode
{
	int m_nValue;
	BSTreeNode *left;
	BSTreeNode *right;
	BSTreeNode(int _value = 0):m_nValue(_value),left(NULL),right(NULL){}
	void add(BSTreeNode* _node)
	{
		if(_node->m_nValue > m_nValue)
		{
			if(right != NULL)
				right->add(_node);
			else
				right = _node;
		}
		else
		{
			if(left != NULL)
				left->add(_node);
			else
				left = _node;
		}
	}
};

//查找二元查找树的最右节点
BSTreeNode* findrightNode(BSTreeNode* BT)
{
	if(BT == NULL)
		return NULL;
	BSTreeNode* rBT = BT;
	while(rBT->right != NULL)
		rBT = rBT->right;
	return rBT;
}

//查找二元查找树的最左节点
BSTreeNode* findleftNode(BSTreeNode* BT)
{
	if(BT == NULL)
		return NULL;
	BSTreeNode* rBT = BT;
	while(rBT->left != NULL)
		rBT = rBT->left;
	return rBT;
}

//把二元查找树转成有序的双向链表
void BST_Blist(BSTreeNode* root)
{
	if(root == NULL)
		return;
	BSTreeNode* left = findrightNode(root->left);
	BSTreeNode* right = findleftNode(root->right);
	BST_Blist(root->left);
	BST_Blist(root->right);
	if(left == root)
		left = NULL;
	if(right == root)
		right = NULL;

	root->left = left;
	if(left != NULL)
		left->right = root;
	root->right = right;	
	if(right != NULL)
		right->left = root;
}

template <typename T, int size=1024>
class queue{
private:
	T data[size];
	int begin, end;
public:
	queue():begin(0),end(0){}
	bool empty()
	{
		return begin == end;
	}
	void push(T& _d)
	{
		if((end +1)%size == begin) 
		{
			cout << "queue is full, cann't push any node." <<endl;
			return;
		}
		data[end] = _d;
		end = (end + 1)%size;
	}

	T& pop(T& _t)
	{
		if(end == begin)
		{
			cout << "queue is empty, cann't pop any node." <<endl;
			return _t;
		}
		_t = data[begin];
		begin = (begin + 1)%size;
		return _t;
	}
};

void print(BSTreeNode* root)
{
	queue<BSTreeNode*> q;
	BSTreeNode* node = root;
	BSTreeNode _n1(-1);//空标记
	q.push(node);
	while(!q.empty())
	{
		BSTreeNode* _bsn = &_n1;
		q.pop(_bsn);
		cout << _bsn->m_nValue << " ";

		if(_bsn->left != NULL)
			q.push(_bsn->left);

		if(_bsn->right != NULL)
			q.push(_bsn->right);
	}
}

int main()
{
	//构建二元查找树
	cout << "构建二元查找树 为:" << endl;
	cout << "   8" << endl;
	cout << "  / /" << endl;
	cout << " 6 10" << endl;
	cout << "/ / / /" << endl;
	cout << "5 7 9 11" << endl;
	BSTreeNode *root = NULL;
	BSTreeNode node1(10);	
	BSTreeNode node2(6);	
	BSTreeNode node3(14);	
	BSTreeNode node4(4);	
	BSTreeNode node5(8);	
	BSTreeNode node6(12);	
	BSTreeNode node7(16);	
	root = &node1;
	root->add(&node2);
	root->add(&node3);
	root->add(&node4);
	root->add(&node5);
	root->add(&node6);
	root->add(&node7);

	//打印二叉查找树
	cout << "按层从左到右,打印二叉查找树" <<endl;
	print(root);
	//转化成排序的双向链表(树)
	BST_Blist(root);
	BSTreeNode *next = findleftNode(root);
	cout << endl << "转化成排序的双向链表 结果为:" << endl;
	while(next != NULL)
	{
		if(next->right != NULL)
			cout << next->m_nValue << "==";
		else
			cout << next->m_nValue;
			
		
		next = next->right;
	}
}

把代码存储为文件main.cpp

在linux环境下编译为:

g++ main.cpp -o main

运行:./main

输出结果为:

构建二元查找树 为:

8

/ /

6 10

/ / / /

5 7 9 11
按层从左到右,打印二叉查找树
10 6 14 4 8 12 16
转化成排序的双向链表 结果为:

4==6==8==10==12==14==16
posted @ 2021-01-28 23:12  天涯学馆  阅读(119)  评论(0编辑  收藏  举报