二叉树遍历

深度优先:前序遍历、中序遍历、后续遍历(删除操作)
不全部保留结点,占用空间少;(有回溯操作)运行速度慢;当搜索树的节点较多,用其他方法易产生内存溢出时,选择方案。(通常使用栈结构,先进后出)
广度优先:层次遍历
保留全部节点,占用空间大;运行速度快(通常使用队列)

原文链接
在这里插入图片描述

在这里插入图片描述

1.前序遍历:ABDHIEJCFG

从二叉树的根节点出发,当第一次到达结点时就输出结点数据,顺序:先左再右
在这里插入图片描述

2.中序遍历:HDIBJEAFCG

从根节点出发,当第二次到达结点时就输出结点数据,顺序:先左再右

在这里插入图片描述

3.后续遍历:HIDJEBFGCA

从根节点出发,当第三次到达结点时就输出结点数据,顺序:先左再右

在这里插入图片描述

4.层次遍历:ABCDEFGHIJ

层次遍历就是按照树的层次自上而下的遍历二叉树

练习题:
在这里插入图片描述
中序遍历:{左子树的结点集合} , root , {右子树的结点集合}
1.由先序顺序得到根节点为F
2.观察前序排序FBACDEGH,知道了F是root,剩下的几点必然在
root的左或右子数的结点
3.观察ABDCEFGH。其中F结点的左侧ABDCE必然是root的左子树结点,GH必然是root的右子树结点,root不在遍历的末尾或开始就说明根节点的两颗子树都不为空。
4.观察左子树ABDCE,按照前序遍历的顺序是BACDE,因此左子树的根节点为B,A的话为B的左子树,DCE则为右子树。再将DEC单独看继续分析。。。判断出B的右子树下的根节点是C,C的左子树是D右子树是E
在这里插入图片描述
还原树结构后,得出A结论

相关知识链接:
相关链接1
相关链接2

#include <stdio.h>
#include <stdlib.h>
#include <queue>
#include <stack>
using namespace std;

typedef struct BinTree
{
	BinTree * pLeft;
	BinTree * pRight;
	char value;
};

BinTree * CreateTree(char value)
{
	BinTree * temp = (BinTree*)malloc(sizeof(BinTree));
	temp->pLeft = NULL;
	temp->pRight = NULL;
	temp->value = value;
	return temp;
}

BinTree * create()
{
	//BinTree * a = CreateTree('A');
	//BinTree * b = CreateTree('B');
	//BinTree * c = CreateTree('C');
	//BinTree * d = CreateTree('D');
	//BinTree * e = CreateTree('E');
	//a->pLeft = b; a->pRight = c;
	//b->pLeft = d; b->pRight = e;
	//c->pLeft = NULL; c->pRight = NULL;
	//d->pLeft = NULL; d->pRight = NULL;
	//e->pLeft = NULL; e->pRight = NULL;
	//return a;

	BinTree * a = CreateTree('A');
	BinTree * b = CreateTree('B');
	BinTree * c = CreateTree('C');
	BinTree * d = CreateTree('D');
	BinTree * e = CreateTree('E');
	BinTree * f = CreateTree('F');
	BinTree * g = CreateTree('G');
	BinTree * h = CreateTree('H');
	f->pLeft = b; f->pRight = g;
	b->pLeft = a; b->pRight = c;
	a->pLeft = NULL; a->pRight = NULL;
	c->pLeft = d; c->pRight = e;
	d->pLeft = NULL; d->pRight = NULL;
	e->pLeft = NULL; e->pRight = NULL;
	h->pLeft = NULL; h->pRight = NULL;
	g->pLeft = NULL; g->pRight = h;
	return f;
	
}

//获取节点个数
int GetTreeSize(BinTree * root)
{
	if(NULL == root)
	{
		return 0;
	}
	else if(root->pLeft == NULL && root->pRight == NULL)
	{
		return 1;
	}
	else
	{
		int lCount = GetTreeSize(root->pLeft);
		int rCount = GetTreeSize(root->pRight);
		return lCount + rCount + 1;
	}
}

#define MAX(a,b) ((a) > (b) ?(a):(b))
int GetTreeHight(BinTree * root)
{	if(NULL == root)
	{
		return 0;
	}

	{
		int lCount = GetTreeHight(root->pLeft);
		int rCount = GetTreeHight(root->pRight);
		return MAX(lCount, rCount)+1;
	}
}


//前序排序
void PreTraverse(BinTree * tree)
{
	if(NULL == tree)
		return;

	printf("%c", tree->value);
	PreTraverse(tree->pLeft);
	PreTraverse(tree->pRight);
}

//中序排序
void InTraverse(BinTree * tree)
{
	if(NULL == tree)
		return;

	InTraverse(tree->pLeft);
	printf("%c", tree->value);
	InTraverse(tree->pRight);
}

//后序排序
void BackTraverse(BinTree * tree)
{
	if(NULL == tree)
		return;

	BackTraverse(tree->pLeft);
	BackTraverse(tree->pRight);
	printf("%c", tree->value);
}

//求某一层节点个数
int CaculateChildCount(BinTree * root, int layer)
{
	if(NULL == root)
		return 0;

	if (layer == 1)
		return 1;

	int lCount = CaculateChildCount(root->pLeft, layer-1);
	int rCount = CaculateChildCount(root->pRight, layer-1);
	return lCount + rCount;
}


//查找:包含value的节点地址,没找到返回NULL
BinTree * SearchTagTree(BinTree * root,char value)
{
	if(NULL == root)
		return NULL;
	
	if (root->value == value)
	{
		return root;
	}
	else
	{
		BinTree * result = SearchTagTree(root->pLeft, value);
		if(result != NULL)
		{
			return result;
		}

		result = SearchTagTree(root->pRight, value);
		if(result != NULL)
		{
			return result;
		}
	}
	return NULL;
}

//广度优先搜索
void BreadthFirsetTraverse(BinTree * root)
{
	queue<BinTree*> nodeQueue;
	nodeQueue.push(root);

	while (!nodeQueue.empty())
	{
		BinTree * node = nodeQueue.front();
		printf("%c' '", node->value);
		nodeQueue.pop();
		if(node->pLeft)
		{
			nodeQueue.push(node->pLeft);
		}

		if(node->pRight)
		{
			nodeQueue.push(node->pRight);
		}
	}
}

//深度优先搜索
//利用栈,先将右子树压栈再将左子树压栈
void DepthFirsetTraverse(BinTree * root)
{
	stack<BinTree*> nodeStack;
	nodeStack.push(root);
	while (!nodeStack.empty())
	{
		BinTree * node = nodeStack.top();
		printf("%c' '", node->value);
		nodeStack.pop();
		if(node->pRight)
		{
			nodeStack.push(node->pRight);
		}

		if(node->pLeft)
		{
			nodeStack.push(node->pLeft);
		}
	}
}

int main()
{
	BinTree * tree = create();
	PreTraverse(tree);
	printf("\n");
	InTraverse(tree);
	printf("\n");
	BackTraverse(tree);
	printf("\n");


	printf("\n节点个数:%d", GetTreeSize(tree));
	printf("\n节点高度:%d", GetTreeHight(tree));
	printf("\n某一层节点个数:%d", CaculateChildCount(tree, 4));
	
	printf("\n广度优先搜索:\n");
	BreadthFirsetTraverse(tree);

	printf("\n深度优先搜索:\n");
	DepthFirsetTraverse(tree);

	system("pause");
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqooopp123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值