数据结构——06树

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:以下是本篇文章正文内容,下面案例可供参考

一、树相关概念

1.树

树:n(n>=0)个结点的有限集合。n = 0 ,空树。
在任意一个非空树中,
1,有且仅有一个特定的根结点
2,当n>1 时,其余结点可分为m个互不相交的有限集合T1,T2,T3.。。。。Tm,其中每一个
集合又是一个树,并且称谓子树。
结点拥有子树的个数称谓结点的度。度为0的结点称谓叶结点。度不为0,称谓分支结点。

树的度数:
是这棵树中,最大的结点的度数,称谓树的度数。
树的深度或高度:
从根开始,根为第一层,根的孩子为第二层。
树的存储
顺序结构,链式结构。

2.二叉树

二叉树,binary tree
n个结点的有限集合,集合要么为空树,要么由一个根结点和两棵互不相交,分别称谓根结点的左子树和右子树的二叉树组成。。

特点,
1,每个结点最多两个子树。
2,左子树和右子树是有顺序的,次序不能颠倒。
3,如果某个结点只有一个子树,也要区分左,右子树。

3.特殊的二叉树

1,斜树,所有的结点都只有左子树,左斜树,所有结点都只有右子树,右树。
2,满二叉树,所有的分支结点都存在左右子树,并且叶子都在同一层上。
3,完全二叉树,对于一颗有n个结点的二叉树按层序编号,如果编号i(1<=i<=n)的结点于同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这可树为完全二叉树。

特性
1,在二叉树的第i层上最多有2^(i-1)个结点 i>=1
2,深度为k的二叉树至多有2^k -1 个结点 k>=1
3,任意一个二叉树T,如果其叶子结点的个数是n0,度数为2的结点数为n2, n0 = n2 +1;
4,有n个结点的完全二叉树深度为(logn/log 2) +1;

4.二叉树遍历方法

层序,
前序,根左右,先访问根,然访问左,访问右。
中序,左根右,先从根开始(不是先访问根),从左开始访问,在访问根,在访问右结点。
后序,左右根,先从根开始(不是先访问根),先访问左,在访问右。在访问根。

二、源码

1.项目结构

代码如下(示例):

	.
├── a.out
├── main.c
├── tree.c
└── tree.h

0 directories, 4 files

2.源码

	#include "tree.h"

int main(int argc, const char *argv[])
{
	BTMNode * pRoot = NULL;
	pRoot = createBinTree();

	midOrder(pRoot);
	printf("\n");
	frontOrder(pRoot);
	printf("\n");
	rearOrder(pRoot);
	printf("\n");
	printf("cnt%d\n",getLenbBTM(pRoot));
	destroy(&pRoot);
	return 0;
}
#include "tree.h"

char tree[] = "ACEG###FH#N###DB#M###" ;
int idx = 0;
int cnt = 0;
BTMNode* createBinTree()
{
	char ch = 0;
	ch = tree[idx++];
	BTMNode* pNode = NULL;
	if('#' == ch)
	{
		return NULL;
	}
	else
	{
		pNode = malloc(sizeof(BTMNode));
		if(NULL == pNode)
		{
			perror("malloc");
			return NULL;
		}
		pNode->data = ch;
		pNode->pL = createBinTree();
		pNode->pR = createBinTree();
	}
	return pNode;

}
void midOrder(BTMNode *pRoot)
{
	if(NULL == pRoot)
	{
		return ;
	}
	midOrder(pRoot->pL);
	printf("%c ",pRoot->data);
	midOrder(pRoot->pR);

}
void frontOrder(BTMNode *pRoot)
{
	if(NULL == pRoot)
	{
		return ;
	}
	printf("%c ",pRoot->data);
	frontOrder(pRoot->pL);
	frontOrder(pRoot->pR);
}
void rearOrder(BTMNode *pRoot)
{
	if(NULL == pRoot)
	{
		return ;
	}
	rearOrder(pRoot->pL);
	rearOrder(pRoot->pR);
	printf("%c ",pRoot->data);

}

int getLen(BTMNode* pRoot)
{
	if(pRoot == NULL)
	{
		return cnt;
	}
	cnt++;
	getLen(pRoot->pR);
	getLen(pRoot->pL);
}
int getLenbBTM(BTMNode* pRoot)
{
	if(pRoot == NULL)
	{
		return 0;
	}
	return (getLenbBTM(pRoot->pL)+getLenbBTM(pRoot->pR)+1);


}
void destroy(BTMNode**ppRoot)
{
	if((*ppRoot) == NULL)
	{
		return ;
	}
	destroy(&(*ppRoot)->pL);
	destroy(&(*ppRoot)->pR);
	free(*ppRoot);
	*ppRoot = NULL;
}

#ifndef _TREE_H_
#define _TREE_H_

#include <stdio.h>
#include <stdlib.h>
typedef char DataType;
typedef struct TreeNode
{
	DataType data;
	struct TreeNode* pL;
	struct TreeNode* pR;
}BTMNode;

extern BTMNode* createBinTree();
extern int cnt;
extern void midOrder(BTMNode *pRoot);
extern void frontOrder(BTMNode*);
extern void rearOrder(BTMNode*);
extern int getLen(BTMNode*);
extern void destroy(BTMNode**);
extern int getLenbBTM(BTMNode* pRoot);
#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值