微软100题 第一题(查找树转换为有序双向链表)

这题是因为看过4,5月份的时候,有人去百度面试的时候提到了,基本思路就是一个中序遍历。

复习一下基础,就把前序,中序,后序的非递归重新写一遍,再把本题的递归和非递归解法也写一下。

个人觉得三种非递归遍历方式中,如果记住左节点访问到底,然后移动一次右节点,再遍历左节点,代码应当还算比较清楚的。

// test_Microsoft_Q1.cpp : 定义控制台应用程序的入口点。
//


//非递归前中后遍历
//中序转化链表
#include "stdafx.h"
#include <iostream>
#include <stack>
using namespace std;




struct Node
{
	int value;
	Node *pleft;
	Node *pright;
	int flag;  //后序遍历专用
};


Node *head = new Node;
Node *tail = new Node;
Node *NodeIndex = head;
stack<Node*> s;

void Insert(Node * & root,int value)
{
	if (root == NULL)
	{
		root = new Node;
		root->value = value;
		root->pleft = NULL;
		root->pright = NULL;
		root->flag = 0;
	}
	if (value > root->value)
	{
		Insert(root->pright,value);
	}
	else if (value < root->value)
	{
		Insert(root->pleft,value);
	}
}

void PreOrder(Node *& root)
{
	if (root == NULL)
	{
		return ;
	}
	cout << root->value << endl;
	PreOrder(root->pleft);
	PreOrder(root->pright);
}




void TurnList(Node * root,Node * head ,Node *tail)
{
	if (root == NULL || head == NULL || tail == NULL)
	{
		return;
	}
	Node *p = root;
	Node *q = head;
	while (!s.empty() || p != NULL)
	{
		while (p)
		{
			s.push(p);
			p = p->pleft;
		}
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			q->pright = p;
			p->pleft = q;
			q = p;
			p = p->pright;
		}
	}
	tail->pleft = q;
}


void ConvertToDoubleList(Node *  node)
{
	NodeIndex->pright = node;
	node->pleft = NodeIndex;
 	NodeIndex = NodeIndex->pright;
}

//递归转链表
void TurnListRecursive(Node *  root)
{
	if (root == NULL)
	{
		return;
	}
	TurnListRecursive(root->pleft);
	ConvertToDoubleList(root);
	TurnListRecursive(root->pright);
}

void MiddleOrder(Node * root)
{
	Node * p = root;
	while ( p != NULL || !s.empty())
	{
		while (p)
		{
			s.push(p);
			p = p->pleft;
		}
		
		p = s.top();
		s.pop();
		cout << p->value << endl;
		p = p->pright;
	}
}

void PreOrderUnRecursive(Node * root)
{
	Node * p = root;
	
	while ( p != NULL || !s.empty())
	{
		while (p)
		{
			cout << p->value << endl;
			s.push(p);
			p = p->pleft;
		}

		p = s.top();
		s.pop();
		p = p->pright;
	}
}


void PostOrder(Node * root)
{
	Node * p = root;
	while ( (p != NULL && p->flag == 0) || !s.empty()) 
	{
		while (p && p->flag == 0)
		{ 
			p->flag = 0;
			s.push(p);
			p = p ->pleft;
		}
		while (!s.empty() && s.top()->flag == 1) //把栈中所有的已访问的节点全抛出
		{
			p = s.top();
			s.pop();
			cout << p->value << endl;
		}
		if (!s.empty())
		{ 
			s.top()->flag = 1; //flag为1表示已经访问的左结点。
			p = s.top();
			p = p->pright;
		}
	}
}




int _tmain(int argc, _TCHAR* argv[])
{
	Node *root = NULL;
	Insert(root,10);
	Insert(root,6);
	Insert(root,14);
	Insert(root,4);
	Insert(root,8);
	Insert(root,12);
	Insert(root,16);
//	Node * tail = NULL;

	TurnList(root,head,tail);
	head->value = 0;
	head->pleft =NULL;
	tail->value = 0;
	tail->pright = NULL;
	Node * p = head->pright;

	while(p)
	{
		cout << p->value << endl;
		p = p->pright;
	}
	p = tail->pleft;
	while (p)
	{
		cout << p->value << endl;
		p = p->pleft;
	}
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值