1.1 树的概念与性质
树的概念:树(Tree)是n(n>=0)个节点的有限集合T
它满足两个条件:
有且仅有一个特定的节点,被称之为根节点(Root)
其余的节点可以分为m(m>=0)个互不相交的有限集合,其中每一个集合又是一棵树,并称为根的子树
度数:一个节点的子树个数称之为该节点的度数,一棵树的度数是指该树中节点的最大度数
层数:节点的层数等于父节点的层数加一,根节点的层数定义为一。一个树的层数是指该树中节点的最大层数
边数:从根节点k1遍历到此节点Kj,并满足ki是ki+1的父节点,就称为一条从k1到kj的路径,路径的长度为j-1,即路径的边数。
叶子(叶节点):没有子节点的节点
1.2 二叉树的概念和性质
二叉树的定义:二叉树是树的一种,它满足树的基本性质,但二叉树和普通树又有所不同,二叉树要求每个节点至多只能拥有两个子节点,并将子节点严格区分为左孩子和右孩子,即使只有一个子节点也要区分左右。
满二叉树:除叶节点以外,度数都为2的二叉树,且叶节点都在最底层
完全二叉树:如果二叉树除去最后一层节点以外为满二叉树,且最后一层的节点从左到右依次分布,且不存在只有右子树的节点,则称该二叉树为完全二叉树。
1.3 完全二叉树的编号机制
如果根节点的编号为1,则之后的每个节点从上到下,从左到右依次编号递增,若节点的总数为n。
某一个节点的编号为i,则可以判断这个节点是否存在左右子树,并且可以得到左右子树的编号。
如果2 * i 如果2 * i + 1
1.4 完全二叉树的存储结构
顺序存储:为了能够清楚每个节点之间的关系,所以需要将没有左右子树的位置预留出来,这样做十分浪费空间,所以我们一般不考虑树的顺序存储。
链式存储:用两个指针分别存储左子树和右子树的地址
1.5 完全二叉树的遍历
先序遍历:先遍历根节点,再遍历左节点,再遍历右节点 —— 根左右
中序遍历:先遍历左节点,再遍历根节点,再遍历右节点 —— 左根右
后序遍历:先遍历左节点,再遍历右节点,再遍历根节点 —— 左右根
1.6 完全二叉树的创建和遍历
1.6.1 bitree.h
#ifndef _BITREE_H
#define _BITREE_H_
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int id; //数据 —— 编号
struct node* lchild; //保存左子树的地址
struct node* rchild; //保存右子树的地址
}bitree;
bitree* comBitreeCreate(int n, int i);
void bitreePreOrder(bitree *root);
void bitreeInOrder(bitree *root);
void bitreePostOrder(bitree *root);
#endif
1.6.2 bitree.c
#include"bitree.h"
//创建一个完全二叉树
//n:结点的总个数
//i :结点的编号 —— i初始值为1
bitree* comBitreeCreate(int n, int i){
bitree *root = (bitree *)malloc(sizeof(bitree));
root->id = i;
//判断左子树是否存在
if(2 * i <= n){
root->lchild = comBitreeCreate(n, 2 * i);
}else{
root->lchild = NULL;
}
//判断右子树是否存在
if(2 * i + 1 <= n){
root->rchild = comBitreeCreate(n, 2 * i + 1);
}else{
root->rchild = NULL;
}
return root;
}
//先序遍历 —— 根左右
void bitreePreOrder(bitree *root){
printf("%d ",root->id);
if(root->lchild != NULL){
bitreePreOrder(root->lchild);
}
if(root->rchild != NULL){
bitreePreOrder(root->rchild);
}
return ;
}
//中序遍历 —— 左根右
void bitreeInOrder(bitree *root){
if(root->lchild != NULL){
bitreePreOrder(root->lchild);
}
printf("%d ",root->id);
if(root->rchild != NULL){
bitreePreOrder(root->rchild);
}
return ;
}
//后序遍历 —— 左右根
void bitreePostOrder(bitree *root){
if(root->lchild != NULL){
bitreePreOrder(root->lchild);
}
if(root->rchild != NULL){
bitreePreOrder(root->rchild);
}
printf("%d ",root->id);
return ;
}
1.6.3 main.c
#include"bitree.h"
int main(int argc, char const *argv[]){
bitree *root = comBitreeCreate(8, 1);
//先序遍历
printf("PreOrder : ");
bitreePreOrder(root);
putchar(10);
//中序遍历
printf("InOrder : ");
bitreeInOrder(root);
putchar(10);
//后序遍历
printf("PostOrder : ");
bitreePostOrder(root);
putchar(10);
return 0;
}