二叉树
来源:互联网 发布:php资源网源码 编辑:程序博客网 时间:2024/04/30 10:13
一.关于树的几个重要概念
1). 度:是指节点拥有的子树数。
2). 深度/高度:从根节点到目的节点x的一条简单路径的长度称为x的深度/高度。国内一般把根节点的高度算为1,而国外有些把根节点的高度算为0,因此计算起来会有差异。
对于4这个节点,度为1,深度/高度为2或3,整个树的高度/深度为3或4。
二.二叉树基本性质
二叉树定义:由n个节点组成(n>=0),构成空树,或者由两棵互不相交的称为左子树和右子树构成。
二叉树基本性质:
1> 在二叉树第i层最多有2^(i-1)个节点(i>=1)。
2> 深度为k的二叉树最多有2^k-1个节点(k>=1)。
3> 对于任何一棵二叉树T,终端节点数为n0,度为2的节点数为n2则n0=n2 + 1。
4> 具有n个节点的完全二叉树的深度为[log2n] + 1,
5> 如果对一棵有n个节点的完全二叉树(深度为[log2n] + 1)的节点按层序编号,对任一节点i(1<=i<=n)有:
(1). 如果i=1,则i是根节点,无双亲;否则其双亲是[i/2].
(2). 如果2i>n,则节点i无左孩子(节点i为叶节点);否则左孩子为2i.
(3). 如果2i+1>n,则节点i无右孩子(节点i为叶子节点);否则右孩子为2i+1.
三.二叉树基本操作
1>数据结构定义
typedef struct tagBinTreeNode{ void* value; struct tagTreeNode * left_child; struct tagTreeNode * right_child;}BinTreeNode;2>二叉树的遍历是指从根节点出发,按造一定次序,访问二叉树的所有节点,使得每个节点被访问一次。D代表根节点,L代表左孩子,R代表右孩子。
(1).前序遍历,DLR,即先访问根节点,再前序遍历左子树和右子树。
(2).中序遍历,LDR,即从根节点开始,中序遍历根节点的左子树然后访问根节点,最后中序遍历根节点的右子树。
(3).后序遍历,LRD,从左到右先子叶后节点的方式遍历访问左右子树,最后是根节点。
(4).层序遍历,从根节点开始逐层向下遍历,同一层从左到右逐个访问。
前序遍历算法:
void PreOrderTraverse(BinTreeNode *pstNode){if(pstNode == NULL){return;}printf("%c", (char)(pstNode->value));PreOrderTraverse(pstNode->left_child);PreOrderTraverse(pstNode->right_child);}
中序遍历算法:
void InOrderTraverse(BinTreeNode *pstNode){if(pstNode == NULL){return;}PreOrderTraverse(pstNode->left_child);printf("%c", (char)(pstNode->value));PreOrderTraverse(pstNode->right_child);}
后序遍历算法:
void PostOrderTraverse(BinTreeNode *ppstNode){if(pstNode == NULL){return;}PreOrderTraverse(pstNode->left_child);PreOrderTraverse(pstNode->right_child);printf("%c", (char)(pstNode->value));}层序遍历:
void LerverOrderTraverse(BinTreeNode *pstNode){if(pstNode == NULL){return;}printf("%c", (char)(pstNode->value));PreOrderTraverse(pstNode->right_child);PreOrderTraverse(pstNode->left_child);}
3>二叉树的建立
假设有这样一个二叉树:
我们可以根据前序中序和后序的方式建立一个二叉树,约定输入*表示空节点。假设一个二叉树的前序遍历输出为:AB*D**C**,中序为:*B*D*A*C*,可以得出中序建立二叉树:
void InOrderCreateBinTree(struct tagBinTreeNode **ppstNode){char chr;scanf("%c", &chr);if(chr == '*'){*ppstNode = NULL;}else{(*ppstNode) = (struct tagBinTreeNode*)malloc(sizeof(struct tagBinTreeNode));if((*ppstNode) == NULL){exit(-1);}memset((*ppstNode), 0x00, sizeof(struct tagBinTreeNode));InOrderCreateBinTree(&(*ppstNode)->left_child); //创建左子树(*ppstNode)->value = chr; //构造根节点InOrderCreateBinTree(&(*ppstNode)->right_child); //创建右子树}}*注意, 虽然说是中序建立二叉树,但是字符的输入顺序应该按照前序列输入方式,设想如果先构造了左子树那么是无法退回父节点的。
四:测试
int main(int arrc, char* argv[]){struct tagBinTreeNode *pstNode = NULL;InOrderCreateBinTree(&pstNode);printf("\n前序输出:");PreOrderTraverse(pstNode);printf("\n中序输出:");InOrderTraverse(pstNode);printf("\n后序输出:");PostOrderTraverse(pstNode);printf("\n层序输出:");LevelOrderTraverse(pstNode);printf("\n");return (0);}输出:
lc@lc-Lenovo:~/work/ProgramTrain$ ./a.out AB*D**C**前序输出:ABDC中序输出:BDAC后序输出:BDCA层序输出:ACBD
- 二叉树、二叉堆
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 二叉树
- 黑马程序员 java知识点分享_异常
- 模板模式
- Linux File Sharing in a Microsoft Active Directory Domain
- Android开发者不可或缺的四大工具
- Android数据库安全解决方案,使用SQLCipher进行加解密
- 二叉树
- 图像搜索是怎么一回事?
- string 动态双向链表的创建、排序,反转等
- 为什么说是“延迟加载实例”呢?
- Android Service完全解析,关于服务你所需知道的一切(上)
- hdu 4685 Prince and Princess
- 网易面试2(社招)
- leetcode:Maximum Subarray(最大的连续子数组) 【面试算法】
- COM组件体系(潘爱民)