二叉树面试题

1.二叉树的前序,中序,后序遍历

//前序遍历非递归
void PrevOrder(BinaryTreeNode* root)
{
	stack<BinaryTreeNode*> s;
	BinaryTreeNode* cur=root;
	while(cur||!s.empty())
	{
		while(cur)
		{
			cout<<cur->_data<<" ";
			s.push(cur);
			cur=cur->_left;
		}
		BinaryTreeNode* top=s.top();
		s.pop();
		cur=top->_right;
	}
	cout<<endl;
}
//中序遍历非递归
void InOrder(BinaryTreeNode* root)
{
	stack<BinaryTreeNode*> s;
	BinaryTreeNode* cur=root;
	while(cur||!s.empty())
	{
		while(cur)
		{
			s.push(cur);
			cur=cur->_left;
		}
		BinaryTreeNode* top=s.top();
		s.pop();
		cout<<top->_data<<" ";
		cur=top->_right;
	}
	cout<<endl;
}
//后序遍历非递归
void PostOrder(BinaryTreeNode* root)
{
	stack<BinaryTreeNode*> s;
	BinaryTreeNode* cur=root;
	BinaryTreeNode* prev=NULL;
	while(cur||!s.empty())
	{
		while(cur)
		{
			s.push(cur);
			cur=cur->_left;
		}
		BinaryTreeNode* top=s.top();
		if(top->_right==NULL||top->_right==prev)
		{
			cout<<top->_data<<" ";
			prev=top;
			s.pop();
		}
		else
		{
		    cur=top->_right;
		}
	}
	cout<<endl;
}
2.实现一颗二叉树的层序遍历

void LevelOrder(BinaryTreeNode* root)
{
	queue<BinaryTreeNode*> q;
	q.push(root);
	while(!q.empty())
	{
		BinaryTreeNode* front=q.front();
		q.pop();
		cout<<front->_data<<" ";
		if(front->_left)
			q.push(front->_left);
		if(front->_right)
			q.push(front->_right);
	}
	cout<<endl;
}
3.求二叉树的高度

int Depth(BinaryTreeNode* root)
{
	if(root==NULL)
		return 0;
	return Depth(root->_left)>Depth(root->_right)?Depth(root->_left)+1:Depth(root->_right)+1;
}
4.求二叉树叶子节点的个数
int LeafSize(BinaryTreeNode* root)
{
	if(root==NULL)
		return 0;
	if(root->_left==NULL&&root->_right==NULL)
		return 1;
	return LeafSize(root->_left)+LeafSize(root->_right);
}
5.求二叉树第k层结点的个数

int KLevel(BinaryTreeNode* root,size_t k)
{
	if(root==NULL||k<0)
		return 0;
	if(k==1)
		return 1;
	return KLevel(root->_left,k-1)+KLevel(root->_right,k-1);//左子树中k-1层的结点个数与右子树中k-1层的节点个数之和
}
6.判断一个结点是否在一颗二叉树中

bool IsBinaryTree(BinaryTreeNode* root,int x)
{
	if(root==NULL)
		return false;
	if(root->_data==x)
		return true;
	return IsBinaryTree(root->_left,x)||IsBinaryTree(root->_right,x);
}
7.判断一颗二叉树是否是平衡二叉树

int Depth(BinaryTreeNode* root)
{
	if(root==NULL)
		return 0;
	return Depth(root->_left)>Depth(root->_right)?Depth(root->_left)+1:Depth(root->_right)+1;
}
//重复遍历
bool IsBalance(BinaryTreeNode* root)
{
	if(root==NULL)
		return true;
	int left=Depth(root->_left);
	int right=Depth(root->_right);
	int dif=left-right;
	if(dif>1||dif<-1)
		return false;
	return IsBalance(root->_left)&&IsBalance(root->_right);
}

8.子树

bool SubTree(BinaryTreeNode* root1,BinaryTreeNode* root2)
{
	if(root2==NULL)
		return true;
	if(root1==NULL)
		return false;
	if(root1->_data!=root2->_data)
		return false;
	return SubTree(root1->_left,root2->_left)&&SubTree(root1->_right,root2->_right);
}
bool NodeSubTree(BinaryTreeNode* root1,BinaryTreeNode* root2)
{
	bool ret=false;
	if(root1!=NULL&&root2!=NULL)
	{
		if(root1->_data==root2->_data)
			ret=SubTree(root1,root2);
		if(!ret)
			ret=NodeSubTree(root1->_left,root2);
		if(!ret)
			ret=NodeSubTree(root1->_right,root2);
	}
	return ret;
}

9.求二叉树的镜像

void Mirror(BinaryTreeNode* root)
{
	if(root==NULL)
		return;
	if(root->_left==NULL&&root->_right==NULL)
		return;
	BinaryTreeNode* temp=root->_left;
	root->_left=root->_right;
	root->_right=temp;
	if(root->_left)
		Mirror(root->_left);
	if(root->_right)
		Mirror(root->_right);
}

10.判断一棵树是不是完全二叉树   树的深度为h,除h层外,其余层节点个数达到最多,第h层所有结点个数都连续集中在最左边
完全二叉树的空洞在层序遍历是在末尾,如果不是完全二叉树遍历到空洞时后边还会有值。所以只有看空后面还有没有值来判断是否是完全二叉树。

bool Iscomplete(BinaryTreeNode* root)
{
	queue<BinaryTreeNode*> q;
	q.push(root);
	while(q.front()!=NULL)
	{
		BinaryTreeNode* temp=q.front();
		q.pop();
		q.push(temp->_left);
		q.push(temp->_right);
	}
	while(!q.empty())
	{
		BinaryTreeNode* ptr=q.front();
		q.pop();
		if(ptr!=NULL)
		{
			return false;
		}
	}
	return true;
}

11.求二叉树两个结点的最近公共祖先
1.二叉树中每个节点都有parent(三叉链)
从给出的结点根据父亲指针向上走,每个路径的结尾都是根节点,可以转换成两个链表求第一个公共节点,则第一个公共结点就是最近祖先。
2.二叉树是搜索二叉树
二叉搜索数是排序的,从根节点开始和输入的两个数进行比较,如果当前结点大于输入的两个数,在当前节点的左子树中找,如果比两个值都小,在右子树中找,第一个在这两个数中间的数就是最近公共祖先。
3.就是一颗普通的树
《1》遍历这棵树,每次遍历到一个结点,判断输入的两个数字是否在他的子树中,如果在,分别遍历他的子节点,看看在不在他们的子树中,一直向下找,如果一个子树中有两个结点,则其子树中没有,则有的就是他的最近公共祖先。(重复遍历)、
《2》用两个链表分别存入到两个结点的路径,把问题转化成求两个链表的最后公共结点。
.

12.二叉搜索树的后序遍历  判断该数组是不是二叉搜索数的后序遍历 数组的最后一个数是根节点 

bool IsPost(int *a,int length)
{
	if(a==NULL||length<=0)
		return false;
	int root=a[length-1];//根节点
	int i=0;
	for(i=0;i<length-1;i++)
	{
		if(root<a[i])
		{
			break;
		}
	}       //左子树
	int j=i;
	for(j=i;j<length-1;j++)
	{
		if(root>a[j])
		{
			return false;
		}
	}   //右子树
	//判断左右子树是不是二叉搜索数
	bool left=true;
	if(i>0)
		left=IsPost(a,i);
	bool right=true;
	if(i<length-1)
		right=IsPost(a+i,length-i-1);
	return (left&&right);
}


14.重建二叉树

BinaryTreeNode* Construct1(int *startpre,int *endpre,int *startin,int *endin)
{
	//前序遍历的第一个结点是根节点
	int rootvalue=startpre[0];
	BinaryTreeNode* root=new BinaryTreeNode(rootvalue);
	root->_left=root->_right=NULL;

	//在中序遍历中找到根节点
	int *rootIn=startin;
	while(rootIn<=endin&&*rootIn!=rootvalue)
		rootIn++;
	if(rootIn==endin&&*rootIn!=rootvalue)
		return NULL;
	//构建左子树
	int leftlength=rootIn-startin;
	int* leftpreend=startpre+leftlength;
	if(leftlength>0)
	{
		root->_left=Construct1(startpre+1,leftpreend,startin,rootIn-1);
	}
	//构建右子树
	if(leftlength<endpre-startpre)
	{
		root->_right=Construct1(leftpreend+1,endpre,rootIn+1,endin);
	}
	return root;
}
BinaryTreeNode* Construct(int* preorder,int* inorder,int length)
{
	if(preorder==NULL||inorder==NULL||length<=0)
		return NULL;
	return Construct1(preorder,preorder+length-1,inorder,inorder+length-1);
}
15.二叉搜索树转换成双向链表      中序遍历二叉搜索树,是排序的。指向左子树的结点的指针调整为链表中指向前一个节点的指针,指向右子树的结点的指针调整为链表中指向后一个结点的指针,遍历到根节点,将二叉树分为三部分,根节点连接到左子树最大的值,连接到右子树最小的值。    把左右子树转换成双向链表在和根节点连接起来。
中序遍历这棵树,放入队列中,然后将队列中的数字连接起来
void Inorder(BinaryTreeNode* root,queue<BinaryTreeNode*>& q)
{
	if(root==NULL)
		return;
	Inorder(root->_left,q);
	q.push(root);
	Inorder(root->_right,q);
}
BinaryTreeNode* ConvertNode(BinaryTreeNode* root)
{
	if(root==NULL)
		return NULL;
	queue<BinaryTreeNode*> q;
	Inorder(root,q);
	BinaryTreeNode* ListHead=q.front();
	q.pop();
	ListHead->_left=NULL;
	BinaryTreeNode* prev=ListHead;
	while(!q.empty())
	{
		BinaryTreeNode* cur=q.front();
		q.pop();
		prev->_right=cur;
		cur->_left=prev;
		cur->_right=NULL;
		prev=cur;
	}
	return ListHead;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值