二叉树总结(常见的二叉树问题,镜像,求两个距离最远的节点的距离等等)

#include<iostream>    //                                    1
#include<stdio.h>     //                            2                3
#include<stdlib.h>    //                       4         5                 6
#include<malloc.h>    //                               7    
#include<queue>
#include<stack>

//1 2 4 0 0 5 7 0 0 0 3 0 6 0 0

using namespace std;

#define Link 0
#define Thread 1

struct NodeBinaryTree
{
	int LTag;
	int RTag;
	int data;
	NodeBinaryTree *Left;
	NodeBinaryTree *Right;
};

NodeBinaryTree *CreatBinaryTree()//创建二叉树
{
	NodeBinaryTree *pt=NULL;
	int ch = 0;
	cin >> ch;
	if (ch == 0)
	{
		pt = NULL;
	}
	else
	{
		pt = (NodeBinaryTree *)malloc(sizeof(NodeBinaryTree));
		pt->data = ch;
		pt->LTag = pt->RTag = Link;
		pt->Left = CreatBinaryTree();
		pt->Right = CreatBinaryTree();
	}
	return pt;

}

void PreTraverTree(NodeBinaryTree *ps)//前序遍历
{
	if (ps != NULL)
	{
		cout<<ps->data<<' ';
		if (ps->Left != NULL) PreTraverTree(ps->Left);
		if (ps->Right != NULL) PreTraverTree(ps->Right);
	}
}

void InTraverTree(NodeBinaryTree *ps)//中序遍历
{
	if (ps != NULL)
	{
		if (ps->Left != NULL) InTraverTree(ps->Left);
		cout << ps->data << ' ';
		if (ps->Right != NULL) InTraverTree(ps->Right);
	}
}

void EndTraverTree(NodeBinaryTree *ps)//后序遍历
{
	if (ps != NULL)
	{
		if (ps->Left != NULL) EndTraverTree(ps->Left);
		if (ps->Right != NULL) EndTraverTree(ps->Right);
		cout << ps->data << ' ';
	}
}

void SequeTraverTree(NodeBinaryTree *ps)//层序遍历
{
	queue<NodeBinaryTree *> q;
	if (ps)
		q.push(ps);
	while (q.empty()==false)
	{
		NodeBinaryTree *temp = q.front();//q.front()代表队列q的首个元素       //法一
		cout << temp->data << "->";
		q.pop();//出队列。每执行一次,最先进去队列的元素出队列,下个元素随即变成q.front()代表的元素
		if (temp->Left)
		{
			q.push(temp->Left);
		}
		if (temp->Right)
		{
			q.push(temp->Right);
		}
		//cout << q.front()->data << "->";//法二
		//if (q.front()->Left)
		//{
		//	q.push(q.front()->Left);
		//}
		//if (q.front()->Right)
		//{
		//	q.push(q.front()->Right);
		//}
		//q.pop();
	}
}

//判断是否为完全二叉树,
bool IsCompleteTree(NodeBinaryTree *ps)
{
	if (ps == NULL)
	return true;	
	queue<NodeBinaryTree *> q;
	q.push(ps);
	NodeBinaryTree *cur = q.front();
	while (cur)
	{
		q.push(cur->Left);
		q.push(cur->Right);
		q.pop();
		cur = q.front();
	}
	//当遇到空节点时,判断剩余的节点是否全部是空节点,若是则为完全二叉树
	while (!q.empty())
	{
		//if (q.front())
		//	return false;
		//q.pop();
		//return true;//队列全为NULL
		while(q.front() == NULL)
		{
			q.pop();
		}
		return false;
	}
}

int DepthTree(NodeBinaryTree *ps)//树的深度(递归法)  。。。。。。
{
	if (ps == NULL)
	{
		return 0;
	}
	if (ps != NULL)
	{
		int leftdepth = DepthTree(ps->Left);
		int righdepth = DepthTree(ps->Right);
		int depth = leftdepth > righdepth ? leftdepth +1: righdepth+1;
		return depth;
		//return (DepthTree(ps->Left) > DepthTree(ps->Right) ? DepthTree(ps->Left) : DepthTree(ps->Right))+1;//此行是上边四行的简化版本
	}
}
/*
int TreeDepth(NodeBinaryTree *ps)//树的深度(非递归法)
{
	if (!ps) return 0;
	queue<NodeBinaryTree *> que;
	que.push(ps); 
	int depth = 0;
	while (!que.empty()) 
	{
		int size = que.size();
			depth++;
		for (int i = 0; i<size; i++) 
		{      //一次处理一层的数据
			NodeBinaryTree *node = que.front();
			que.pop();
			if (node->Left) que.push(node->Left);
			if (node->Right) que.push(node->Right);
		}
	}
	return depth;
}
*/
int TreeDepth(NodeBinaryTree *ps)//树的深度(非递归方法)
{
	if (ps == NULL)
		return 0;
	queue<NodeBinaryTree *> q;
	int depth = 0;
	q.push(ps);//根节点放入队列
	while (!q.empty())//队列不为空
	{
		depth++;
		int siz = q.size();//获取当前状态下该层的数据个数,也就是队列目前存储的数据个数,目的是用下边的for循环,使下一层数据进入队列
		for (int i = 0; i < siz; i++)//每次处理一层数据
		{
			if (q.front()->Left)
				q.push(q.front()->Left);
			if (q.front()->Right)
				q.push(q.front()->Right);
			q.pop();
		}
	}
	return depth;
}

bool IsBalanceTree(NodeBinaryTree *ps)//判断是否为平衡树   
{
	if (ps == NULL)
		return NULL;
	int left_height = TreeDepth(ps->Left);
	int right_height = TreeDepth(ps->Right);
	int sub_height = abs(left_height - right_height);
	if (sub_height > 1)
		return false;
	return IsBalanceTree(ps->Left) && IsBalanceTree(ps->Right);//   a&&b短路与,a为falseb不执行,a为trueb还要执行
}  
                                                            //   a||b短路或,a为true,不在判断b

int LeafSize(NodeBinaryTree *ps)//计算叶子节点个数
{
	if (ps == NULL)
		return 0;
	if (ps->Left == NULL&&ps->Right == NULL)
		return 1;
	if (ps)
		//return LeafSize(ps->Left) + LeafSize(ps->Right);
	{
		int l = LeafSize(ps->Left);
		int r = LeafSize(ps->Right);
		int a = l + r;
		return a;
	}
}

int LevelK_NodeSize(NodeBinaryTree *ps, int level)//计算第level层节点个数
{
	if (ps == NULL || level <= 0)
		return 0;
	if (ps!=NULL&&level == 1)
		return 1;
	return LevelK_NodeSize(ps->Left,level-1) + LevelK_NodeSize(ps->Right,level-1);//为什么是level-1,因为判断左右子树时,不会计入根节点
}

bool NodeIsInTree(NodeBinaryTree *ps, NodeBinaryTree *test)//给定一个节点,判断该节点是否在该树中
{
	if (ps == NULL || test == NULL)
		return false;
	if (ps->data == test->data)
		return true;
	if (NodeIsInTree(ps->Left, test) || NodeIsInTree(ps->Right, test))
		return true;
	else
		return false;
}
/*
void MirrorBinaryTree(NodeBinaryTree *ps)//镜像二叉树.当树为空或者只有跟节点时直接返回,当左右子树都不为空时,依此交换
{
	if (ps == NULL || (ps->Left == NULL&&ps->Right == NULL))
		return;
	NodeBinaryTree *temp;
	temp = ps->Left;
	ps->Left = ps->Right;
	ps->Right = temp;
	if (ps->Left)
		MirrorBinaryTree(ps->Left);
	if (ps->Right)
		MirrorBinaryTree(ps->Right);
}
*/
void MirrorBinaryTree(NodeBinaryTree *ps)//非递归法实现二叉树的镜像
{
	if (ps == NULL)
		return;
	stack<NodeBinaryTree *> s;
	s.push(ps);
	while (!s.empty())
	{
		NodeBinaryTree *root=s.top();
		s.pop();
		NodeBinaryTree *temp=root->Left;
		root->Left = root->Right;
		root->Right = temp;
		if (root->Left)
			s.push(root->Left);
		if (root->Right)
			s.push(root->Right);
		
	}
}

int Hight(NodeBinaryTree *pr, int &distance)
{
	if (pr == NULL)
		return 0;
	int LeftH = Hight(pr->Left,distance);
	int RightH = Hight(pr->Right, distance);
	if (LeftH + RightH > distance)
		distance = LeftH + RightH;
	return LeftH > RightH ? LeftH + 1 : RightH + 1;
}

int GetFastDistance(NodeBinaryTree *ps)//求二叉树最远两个节点之间的距离
{
	int distance = -1;
	Hight(ps, distance);
	return distance;
}

NodeBinaryTree *pre = NULL;


void InThreadBinaryTree(NodeBinaryTree *ps)//(中序遍历)线索话二叉树   左、中、右
{
	if (ps)
	{
		InThreadBinaryTree(ps->Left);
		if (!ps->Left)//没有左子树
		{
			ps->LTag = Thread;
			ps->Left = pre;
		}
		if (pre != NULL&&pre->Right == NULL)//前驱没有右子树
		{
			pre->RTag = Thread;
			pre->Right = ps;
		}
		pre = ps;
		InThreadBinaryTree(ps->Right);
	}
}

void InOrderBinaryTree(NodeBinaryTree *ps)//中序话遍历已经线索话的二叉树并输出
{
	NodeBinaryTree *p = ps;
	while (p != NULL)
	{
		while (p->LTag == Link)
		{
			p = p->Left;
		}
		cout << p->data << " ";

		//打印出当前节点的后继
		while (p->RTag == Thread && p->Right != NULL)
		{
			p = p->Right;
			cout << p->data << " ";
		}

		//指向该节点的后继 
		p = p->Right;
	}
	cout << endl;
}



int main(void)
{
	NodeBinaryTree* pRoot = NULL;
	
	/* 创建二叉树 */
	pRoot = CreatBinaryTree();

	cout << "前序遍历输出:" << ' ';
	PreTraverTree(pRoot);
	cout << endl;

	cout << "中序遍历输出:" << ' ';
	InTraverTree(pRoot);
	cout << endl;

	/* 中序线索化该二叉树 */
	//InThreadBinaryTree(pRoot);

	//cout << "中序线索化之后,中序遍历输出:" << ' ';
	//InOrderBinaryTree(pRoot);

	cout << "层序遍历" << ' ';
	SequeTraverTree(pRoot);
	cout << endl;

	cout << "判断是否为完全二叉树:";
	if (IsCompleteTree(pRoot)==true)
		cout << "是完全二叉树" << endl;
	else
		cout << "不是完全二叉树" << endl;

	cout << "树的深度(递归法):";
	cout << DepthTree(pRoot) << endl;

	cout << "树的深度(非递归法):";
	cout << TreeDepth(pRoot) << endl;

	cout << "判断是否为平衡二叉树:";
	if (IsBalanceTree(pRoot) == true)
		cout << "是平衡二叉树" << endl;
	else
		cout << "不是平衡二叉树" << endl;

	cout << "叶子节点的个数:";
	cout << LeafSize(pRoot) << endl;

	cout << "手动输入一个整数level,";
	int level;
	cin >> level;
	cout << "输出第level层节点个数:"<<LevelK_NodeSize(pRoot, level) << endl;

	NodeBinaryTree *test=NULL;
	cout << "判断给定的节点test,是否在树中;输入一个数,创建一个节点:";//输入新节点的格式参考创建二叉树时的格式(例:输入一个存储数据为3的节点,应输入3 0 0.3必须后接两个0,因为本程序中,创建二叉树的部分是通过判断两个孩子节点是否为0结束输入)
	test = CreatBinaryTree();
	if (NodeIsInTree(pRoot, test))
		cout << "该节点在二叉树中。" << endl;
	else
		cout << "该节点不在此二叉树中。" << endl;

	cout << "输出镜像二叉树:";
	MirrorBinaryTree(pRoot);
	cout << "先序遍历输出镜像后的二叉树 ";
	PreTraverTree(pRoot);
	cout << endl;

	cout << "求二叉树最远两个节点之间的距离:";
	cout << GetFastDistance(pRoot) << endl;

	system("pause");

	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值