树和二叉树
树的基本概念
树是
n
n
()节点的有限集。
子树设A是T有根树的一个节点,b是A的一个子结点,由b及b的后代衍生的树称之为T的子树。
树的结点包含一个数据元素及指向其子树的分支。结点拥有的子树数称为结点的度。度数为零的结点称为叶子或者终端结点。度数不为零的结点称之为非终端结点或分支结点。分支结点也称作内部结点。数的度是树内各个结点的度的最大值。
结点的子树的根称之为该结点的孩子,该结点则称为孩子的双亲。
树中结点的最大层次称之为树的深度或高度。
树中结点的各个子树看成从左至右是有次序的(不能互换),则称该树为有序树,否则则称为无序树
二叉树的基本概念及性质
二叉树的特点是每个结点至多有两颗子树(即二叉树中不存在度大于2的结点),且二叉树有左右之分,其次序不能任意颠倒。
二叉树:
* 满二叉树:深度为
k
k
且有 - 1 个结点的二叉树。
* 完全二叉树
* 非完全二叉树
* 说不明白了 看下图吧
一般二叉树的性质:
* 在二叉树的第
i
i
层上至多有个结点(
i>=1
i
>=
1
)。
* 深度为
k
k
的二叉树至多有 - 1个结点。
* 对任何一颗二叉
T
T
,如果其终端节点数为,度为2的结点数
n2
n
2
,则
n0
n
0
=
n2
n
2
+ 1 。
完全二叉树性质:
* 具有
n
n
个结点的完全二叉树的深度为
二叉树的遍历:
* 先序遍历:根节点 –> 左子树 –> 右子树
* 中序遍历:左子树 –> 根节点 –> 右子树
* 后序遍历:左子树 –> 右子树 –> 根节点
* 层次遍历:按层次遍历
具体实现如下:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 100
typedef int ElemType;
typedef struct bitNode{
ElemType data;
struct bitNode* lchild;
struct bitNode* rchild;
}BitNode;
typedef BitNode* BitTree;
BitTree preInitTree() {
BitTree tree;
ElemType ch;
scanf("%d",&ch);
getchar();
if (ch == 0) {
tree = NULL;
} else {
tree = (BitTree)malloc(sizeof(BitNode));
tree -> data = ch;
printf("请输入%d的左结点:",ch);
tree -> lchild = preInitTree();
printf("请输入%d的右结点:",ch);
tree -> rchild = preInitTree();
}
return tree;
}
//先序遍历
void preOrderTraverse(BitTree root, void (* visit)(ElemType data)) {
if (root == NULL) {
return;
} else {
visit(root -> data);
preOrderTraverse(root -> lchild, visit);
preOrderTraverse(root -> rchild, visit);
}
}
//中序遍历
void inOrderTraverse(BitTree root, void (* visit)(ElemType data)) {
if (root == NULL) {
return;
} else {
inOrderTraverse(root -> lchild, visit);
visit(root -> data);
inOrderTraverse(root -> rchild, visit);
}
}
//后序遍历
void postOrderTraverse(BitTree root, void (* visit)(ElemType data)) {
if (root == NULL) {
return;
} else {
postOrderTraverse(root -> lchild, visit);
postOrderTraverse(root -> rchild, visit);
visit(root -> data);
}
}
//层序遍历
void levelOrderTraverse(BitTree root, void (* visit)(ElemType data)) {
BitTree quene[MAXSIZE];
quene[0] = root;
int front = 0;
int rear = 1;
while (front < rear) {
if (quene[front]) {
visit(quene[front] -> data);
quene[rear++] = quene[front] -> lchild;
quene[rear++] = quene[front] -> rchild;
}
front++;
}
}
void printTree(ElemType data) {
printf("%d",data);
}
int main(int argc, const char * argv[]) {
printf("请先序输入二叉树结点:");
BitTree tree = preInitTree();
printf("\n先序遍历结果:\n");
preOrderTraverse(tree, printTree);
printf("\n中序遍历结果:\n");
inOrderTraverse(tree, printTree);
printf("\n后序遍历结果:\n");
postOrderTraverse(tree, printTree);
printf("\n层序遍历结果:\n");
levelOrderTraverse(tree, printTree);
printf("\n");
return 0;
}