【嵌入式学习历程11】数据结构之二叉树

树的概念
树(Tree)是n(n>=0)个结点的有限集。n=0的时候称为空树,在任意一颗非空树中:(1)有且仅有一个特定的称为根(root)的结点;(2)当n>1时,其余结点可以分为m(m>0)个互不相交的有限集T1、T2、T3…Tm,其中,每一个集合本身又是一棵树,并且称为跟的子树。

这里写图片描述

  • 结点
    树的结点包含一个数据元素及若干个指向其子树的分支。
    *度
    结点拥有的子树称为结点的度。
    *叶结点
    度为0的结点称为叶结点或者终端结点。
    *分支结点
    度不为0的结点称为非终端结点或者分支结点。
    *孩子、双亲
    结点的子树的跟称为该结点的孩子,相应的,该结点称为孩子的双亲。
    *深度
    树中结点最大层次称为树的深度。
    二叉树
    二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。(通俗地讲就是一个结点最多有两个分支)
    二叉树的特点
    1.每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。
    2.左子树和右子树是有顺序的,次序不能任意颠倒。
    3.即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。

二叉树的性质
1.在二叉树的第i层上至多有 2^(i - 1) 个结点
2.深度为k的二叉树至多有 2^k -1个结点
3.对任何一棵二叉树T,如果其终端结点数为n,度为2的结点数为m,则n=m+1
4.具有n个结点的完全二叉树的深度为 log2(n) + 1

二叉树的遍历
1、先序遍历
若二叉树为空, 则空操作返回,否则先访问根结点,然后先序遍历左子树,再先序遍历右子树,如图:ABDGHCEI
这里写图片描述

2、中序遍历
若树为空,则空操作返回,否则从根结点开始(注意并不是访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树,如图:GDHBAEICF

这里写图片描述

3、后序遍历
若树为空,则空操作返回,否则从左到右,先叶子后结点的方式遍历访问左右子树,最后是访问根结点,如图:GHDBIEFCA
这里写图片描述

下面,我们用程序来实现二叉树的三种遍历:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10

typedef struct node
{
	int data;
	struct node *left, *right;
}TreeNode;

TreeNode *CreateTree (int *a, int len)
{
	int i;
	TreeNode *node[100] = {0};

	for (i = 0; i < len; i++)
	{
		node[i] = (TreeNode *)malloc(sizeof(TreeNode));
		if (NULL == node[i])
		{
			return NULL;
		}

		node[i]->data = a[i];
		node[i]->left = NULL;
		node[i]->right = NULL;
	}

	for (i = 0; i < len / 2; i++)
	{
		node[i]->left = node[2 * i + 1];
		node[i]->right = node[2 * i + 2];
	}
	return node[0];
}

void PreOrderTree(TreeNode *R)
{
	if (NULL == R)
	{
		return;
	}

	printf("%d ", R->data);
	PreOrderTree(R->left);			//递归调用
	PreOrderTree(R->right);
}

void MidOrderTree(TreeNode *R)
{
	if (NULL == R)
	{
		return;
	}

	MidOrderTree(R->left);			
	printf("%d ", R->data);
	MidOrderTree(R->right);
}

void BackOrderTree(TreeNode *R)
{
	if (NULL == R)
	{
		return;
	}

	BackOrderTree(R->left);			
	BackOrderTree(R->right);
	printf("%d ", R->data);

}

int main()
{
	int a[MAXSIZE] = {0};
	int i;
	int length = sizeof(a) / sizeof(a[0]);
	TreeNode *Root = NULL;

	printf("Please input 10 number:\n");
	for (i = 0; i < MAXSIZE; i++)
	{
		scanf("%d", &a[i]);
	}

/* 初始化一颗二叉树 */
	Root = CreateTree(a, length);

/* 树的三种遍历 */
	printf("先序遍历:\n");
	PreOrderTree(Root);
	printf("\n\n");
	printf("中序遍历:\n");
	MidOrderTree(Root);
	printf("\n\n");
	printf("后序遍历:\n");
	BackOrderTree(Root);
	printf("\n\n");


	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值