常见的二叉树面试题

/*****************************算法思想:使用的是栈结构
步骤一:如果节点有左子树,则将该节点入栈;如果该节点没有左子树,则访问该节点
步骤二:如果节点有右子树,则重复步骤一;如果没有右子树(则说明该节点文访问完毕),则根据栈顶指示回退,访问栈顶元素,并访问右子树,重复步骤一
若栈为空,表示遍历完成。*******************************/
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <string.h>
#include <stack>
#include <stdlib.h>
#include <queue>
using namespace std;
typedef struct BiNode
{
	int data;
	struct BiNode *Lchild, *Rchild;
}BiNode,*BinTree;

typedef struct node
{
	BinTree btnode;
	bool isFirst;

}BtNnode;
BinTree Creat(BinTree T)
{
	int num = 0;
	scanf("%d",&num);

	if (num == 0)
	{ T = NULL;
	return T; 
	}
	T = (BinTree)malloc(sizeof(BiNode));
	T->data = num;
	T->Lchild = Creat(T->Lchild);
	T->Rchild = Creat(T->Rchild);
	return T;
}
/*
对于任何一个节点均可将其看做是根节点,因此可以直接访问。访问后,按照相同的规则访问其左孩子,其次再访问其右孩子。
对任何一个节点P:
1)访问它,并将它入栈;
2)然后判断其左孩子是否是空,若不为空,则将其左孩子置为当前的P节点,并循环步骤1)
若为空,则取出栈顶节点,并将栈顶的右孩子置为当前节点p,循环步骤1),并出栈。
3)直至到P为空或者栈为空。
*/
void preorder1(BinTree T)
{
	stack<BinTree> s;
	BinTree root = T;
	while (root != NULL || (!s.empty()))
	{
		while (root != NULL)
		{
			cout << root->data << endl;
			s.push(root);
			root = root->Lchild;
		}
		if (!s.empty())
		{
			root = s.top();
			s.pop();
			root = root->Rchild;
		}
	
   }
}
void Inoder1(BinTree T)
{
	stack<BinTree>s;
	BinTree root = T;
	while (root != NULL ||(!s.empty()))
	{
		while (root != NULL)
		{
			s.push(root);
			root = root->Lchild;
		}
		if (!s.empty())
		{
			root = s.top();
			cout << root->data << endl;
			s.pop();
			root = root->Rchild;
		}
	}
}
/*对任意一个节点P,将其入栈,然后沿着其左子树的方向遍历,直至搜素到没有左孩子的节点,此时该节点第一次出现在栈顶。但是还不能将其弹出,因为
她的右孩子还没有遍历,所以接下来对其右孩子按照相同的规则进行处理,当访问问其右孩子节点时,该节点有一次出现在栈顶,此时就可以访问并弹出该节点了。
也就是说当该节点第二次出现在栈顶时,才可以访问并弹出。因此需要设置一个访问的标志。
*/
void postorder1(BinTree T)
{
	stack<BtNnode*>s;
	BinTree p = T;
	BtNnode* temp = NULL;
	while ((p != NULL) || !s.empty())
	{
		while (p != NULL)
		{
			BtNnode* btn = (BtNnode*)malloc(sizeof(BtNnode));
			btn->btnode = p;
			btn->isFirst = true;
			s.push(btn);
			p = p->Lchild;
		}
	
	if (!s.empty())
	{
		temp = s.top();
		s.pop();
		if (temp->isFirst == true)
		{
			temp->isFirst = false;
			s.push(temp);
			p = temp->btnode->Rchild;
		}
		else
		{
			cout << temp->btnode->data;
			p = NULL;
		}
	
	}
	}
}
/*要保证根节点在其左右孩子节点都被访问过后,或者其左子树和右子树均为空时,才可以访问该 根节点*/
void postorder2(BinTree T)
{
	stack<BinTree>s;
	BinTree cur = NULL;
	BinTree pre = NULL;
	s.push(T);
	while (!s.empty())
	{
		cur = s.top();
		if ((cur->Lchild == NULL&&cur->Rchild == NULL) || (pre != NULL && (pre == cur->Lchild || pre == cur->Rchild)))
		{
			cout << cur->data << endl;
			s.pop();
			pre = cur;
		}
		else
		{
			if (cur->Rchild != NULL)
				s.push(cur->Rchild);
			if (cur->Lchild != NULL)
				s.push(cur->Lchild);
		}
	}
}
int Getnumleaf(BinTree T)
{
	int num = 0;
	BinTree p = T;
	if (p == NULL) return 0;
	if (p->Lchild == NULL&&p->Rchild == NULL)
	{
		return 1;
	}
	return Getnumleaf(p->Lchild) + Getnumleaf(p->Rchild);
}
int Getdepth(BinTree T)
{
	if (T == NULL){ return 0; }
	int leftdepth = Getdepth(T->Lchild);
	int rightdepth = Getdepth(T->Rchild);
	return (leftdepth > rightdepth) ? (leftdepth + 1): (rightdepth + 1);
}
int Getdepth1(BinTree T)
{
	queue<BinTree>q;
	q.push(T);
	int level = 0;
	int layersize = 0;
	int cnt = 0;
	BinTree temp = NULL;
	while (!q.empty())
	{
		level++;
		layersize = q.size();
		cnt = 0;
		while (cnt < layersize)
		{
			cnt++;
			temp = q.front();
			q.pop();
			if (temp->Lchild != NULL)
				q.push(temp->Lchild);
			if (temp->Rchild != NULL)
				q.push(temp->Rchild);

		}

	}
	return level;
	
}
void printree(BinTree T)   // 按层次遍历树
{
	if (T == NULL)return;
	queue<BinTree>q;
	q.push(T);
	while (!q.empty())
	{
		BinTree temp = q.front();
		cout << temp->data << endl;
		q.pop();
		if (temp->Lchild != NULL)
			q.push(temp->Lchild);
		if (temp->Rchild != NULL)
			q.push(temp->Rchild);
	}
}
/*判断一个节点是否在树中*/
bool Searchnode(BinTree T,BiNode* r)
{
	bool res = false;
	BinTree p = T;
	stack<BinTree>s;
	if (T == NULL)return false;
	while (p!=NULL||!s.empty())
	{  
		while (p != NULL)
		{
			if (p==T)
			{
				res = true;
				break;
			}
			s.push(p);
			p = p->Lchild;
		}
		if (!s.empty())
		{
			p = s.top();
			s.pop();
			p = p->Rchild;
		}
	}
	return res;
}
/*
根据前序和中序序列重建二叉树
*/
vector<int> preorder = {1,2,4,7,3,5,6,8};
vector<int>inorder= {4,7,2,1,5,3,8,6};
BinTree reconstructree(vector<int>pre, int prebegin, int preend, vector<int>inorder, int inbegin, int inend)
{
	BiNode* root = new BiNode();
	root->data = pre[prebegin];
	if (preend < prebegin || inend < inbegin)return NULL;
	for (int i = inbegin; i <= inend; i++)
	{
		if (inorder[i] == preorder[prebegin])
		{
			root->Lchild = reconstructree(preorder, prebegin + 1, prebegin + i - inbegin, inorder, inbegin, i - 1);
			root->Rchild = reconstructree(preorder, prebegin + 1 + i - inbegin, preend, inorder, i + 1, inend);
		}
	}
	return root;
}
BinTree reConstructBinaryTree(vector<int>pre, vector<int>vin)
{
	BinTree root = reconstructree(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
	return root;

}


void main()
{
	/*BiNode t1, t2, t3, t4, t5, t6;
	memset(&t1, 0, sizeof(BiNode));
	memset(&t2, 0, sizeof(BiNode));
	memset(&t3, 0, sizeof(BiNode));
	memset(&t4, 0, sizeof(BiNode));
	memset(&t5, 0, sizeof(BiNode));
	memset(&t6, 0, sizeof(BiNode));
	t1.data = 1;
	t2.data = 2;
	t3.data = 3;
	t4.data = 4;
	t5.data = 5;
	t6.data = 6;
	t1.Lchild = &t2;
	t1.Rchild = &t3;
	t2.Lchild = &t4;
	t3.Lchild = &t5;
	t3.Rchild = &t6;*/
	//preorder1(&t1);
			/*BinTree T=NULL;
			BinTree Root = Creat(T);
			preorder1(Root);
			printf("\n\n");
			Inoder1(Root);
			printf("\n\n");
			postorder1(Root);
			printf("\n\n");
			postorder2(Root);
			printf("\n\n");
			int number = Getnumleaf(Root);
			printf("%d\n",number);
			printf("\n\n");
			int depth = Getdepth1(Root);
			printf("%d\n", depth);
			printf("\n\n");
			printree(Root);*/
	/*inorder(&t1);
	printf("\n");
	postorder(&t1);
	printf("\n");
	//int r=countleafnum(&t1);

	//printf("%d", r);

	int sum = 0;
	countleafnum1(&t1,&sum);
	printf("%d", sum);*/
	/*for (vector<int>::iterator it = preorder.begin(); it != preorder.end(); it++)
	{
		cout << *it << endl;
	}
	printf("\n\n");
	for (vector<int>::iterator it = inorder.begin(); it != inorder.end(); it++)
	{
		cout << *it << endl;
	}*/
	BinTree T = NULL;
	T = reConstructBinaryTree(preorder, inorder);
	Inoder1(T);
	system("pause");

}

    原文作者:luckystar_sai
    原文地址: https://blog.csdn.net/qq_33573235/article/details/79488468
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞