树是常见数据结构
二叉树是指点度最多只有2的特殊树
注意二叉树的左右子树存在顺序
另外附上一些二叉树的性质 :
1 二叉树的第i层最多有2的i-1次方个结点
2 深度为i的二叉树最多有(2的i次方)-1个结点
3 二叉树的度为0的结点的数量等于度为 2的结点的数量+1
4 具有n个结点的完全二叉树的深度为|log₂n|+1
5 完全二叉树的父节点为N,子左结点为2N,子右节点为2N+1
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100 //存储空间分配大小
#define MAX_TREE_SIEZ 100 //二叉树的最大结点数
#define EMPTY_NODE_NUM 0 //空节点的值
typedef int Status; //表示函数返回的状态
typedef int TElemType; //表示结点元素的类型
typedef TElemType SqBiTree[MAX_TREE_SIEZ]; //顺序结构的二进制树
typedef struct
{
//按满二叉树计算
int level; //结点的层
int order; //本层序号
}Position;
Status InitBiTree(SqBiTree T) {
memset(T, EMPTY_NODE_NUM,sizeof(TElemType)* MAX_TREE_SIEZ);
return OK;
}
Status CreateBiTree(SqBiTree T) {
printf("为了演示程序,自动创建一个二叉树\n");
int i = 0;
while (i < 10) {
T[i] = i + 1;
if (i != 0 && T[i] != EMPTY_NODE_NUM && T[(i + 1) / 2 - 1] == EMPTY_NODE_NUM) {
printf("结点为%d的非空节点无双亲结点\n",i);
exit(EXIT_FAILURE);
}
i++;
}
while (i < MAX_TREE_SIEZ)
{
T[i] = EMPTY_NODE_NUM;
i++;
}
return OK;
}
Status ClearTree(SqBiTree T) {
memset(T, EMPTY_NODE_NUM, sizeof(TElemType) * MAX_TREE_SIEZ);
return OK;
}
Status BiTreeEmpty(SqBiTree T) {
//根结点为空则树为空
if (T[0] == EMPTY_NODE_NUM) {
return TRUE;
} else {
return FALSE;
}
}
int BiTreeDepth(SqBiTree T) {
if (BiTreeEmpty(T)) {
printf("BiTreeDepth fail:空树\n");
}
int treeNodeCnt = 0; //存储树中的结点数
int treeDepth = -1;
for (treeNodeCnt = MAX_TREE_SIEZ - 1; treeNodeCnt > 0; treeNodeCnt--) {
if (T[treeNodeCnt] != EMPTY_NODE_NUM) {
break;
}
}
treeNodeCnt++;//下标+1 = 结点数
do {
treeDepth++;
} while (treeNodeCnt >= powl(2, treeDepth));//算法和完全二叉树的特性有关
return treeDepth;
}
//当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义
Status Root(SqBiTree T, TElemType* e) {
if (BiTreeEmpty(T)) {
return ERROR;
} else {
*e = T[0];
return OK;
}
}
//操作结果: 返回处于位置e(层,本层序号)的结点的值
TElemType Value(SqBiTree T, Position p) {
int index = (int)powl(2, p.level - 1) + p.order - 2;
return T[index];
}
// 操作结果: 给处于位置e(层,本层序号)的结点赋新值value
Status Assign(SqBiTree T,Position p,TElemType value){
if (BiTreeEmpty(T)) {
return ERROR;
}
int index = (int)powl(2, p.level - 1) + p.order - 2;
if (index != 0 && T[index] != EMPTY_NODE_NUM && T[(index + 1) / 2 - 1] == EMPTY_NODE_NUM) {
printf("结点为%d的非空节点无双亲结点\n",index);
return ERROR;
}
T[index] = value;
return OK;
}
TElemType Parent(SqBiTree T,TElemType son){
if (BiTreeEmpty(T)) {
//空树
return EMPTY_NODE_NUM;
}
int index;
//找到指定元素的位置
for(index = 0; index < MAX_TREE_SIEZ; index++){
if(T[index] == son){
//换算成父元素的位置
index = (index+1)/2 - 1;
return T[index];
}
}
//没有找到
return EMPTY_NODE_NUM;
}
TElemType LeftChild(SqBiTree T,TElemType e){
if (BiTreeEmpty(T)) {
//空树
return EMPTY_NODE_NUM;
}
int index;
//找到指定元素的位置
for(index = 0; index < MAX_TREE_SIEZ; index++){
if(T[index] == e){
//换算成父元素的位置
index = index * 2 + 1;
}
//判断索引的合法性
if(index >= MAX_TREE_SIEZ){
printf("LeftChild's parent index illegal\n");
} else {
return T[index];
}
}
//没有找到
return EMPTY_NODE_NUM;
}
TElemType RightChild(SqBiTree T,TElemType e){
if (BiTreeEmpty(T)) {
//空树
return EMPTY_NODE_NUM;
}
int index;
//找到指定元素的位置
for(index = 0; index < MAX_TREE_SIEZ; index++){
if(T[index] == e){
//换算成父元素的位置
index = index * 2 + 2;
}
//判断索引的合法性
if(index >= MAX_TREE_SIEZ){
printf("RightChild's parent index illegal\n");
} else {
return T[index];
}
}
//没有找到
return EMPTY_NODE_NUM;
}
TElemType LeftSibling(SqBiTree T,TElemType e){
if (BiTreeEmpty(T)) {
//空树
return EMPTY_NODE_NUM;
}
int index;
//找到指定元素的位置
for(index = 0; index < MAX_TREE_SIEZ; index++){
if(T[index] == e && index%2 == 0){
//找到结点,并且为右节点
return T[index - 1];
}
}
//没有找到
return EMPTY_NODE_NUM;
}
TElemType RightSibling(SqBiTree T,TElemType e){
if (BiTreeEmpty(T)) {
//空树
return EMPTY_NODE_NUM;
}
int index;
//找到指定元素的位置
for(index = 0; index < MAX_TREE_SIEZ; index++){
if(T[index] == e && index%2){
//找到结点,并且为左节点
return T[index + 1];
}
}
//没有找到
return EMPTY_NODE_NUM;
}
//前序遍历
void PreOrderTraverse(SqBiTree T,int index){
if(T[index] == EMPTY_NODE_NUM){
return;
}
printf("%d\n",T[index]);
PreOrderTraverse(T,index*2 + 1);//左结点
PreOrderTraverse(T,index*2 + 2);//右结点
}
//中序遍历
void InOrderTraverse(SqBiTree T,int index){
if(T[index] == EMPTY_NODE_NUM){
return;
}
InOrderTraverse(T,index*2 + 1);//左结点
printf("%d\n",T[index]);
InOrderTraverse(T,index*2 + 2);//右结点
}
//后序遍历
void PostOrderTraverse(SqBiTree T,int index){
if(T[index] == EMPTY_NODE_NUM){
return;
}
PostOrderTraverse(T,index*2 + 1);//左结点
PostOrderTraverse(T,index*2 + 2);//右结点
printf("%d\n",T[index]);
}
//层序遍历
void LevelOrderTraverse(SqBiTree T,int index){
int lastIndex;
for(lastIndex = MAX_TREE_SIEZ - 1;lastIndex >= 0;lastIndex--){
if(T[lastIndex] != EMPTY_NODE_NUM){
//找到最后的结点
break;
}
}
if(index < 0 && index > lastIndex){
//传入的索引非法
return;
}
for(;index <= lastIndex; index++){
if(T[index] != EMPTY_NODE_NUM){
printf("%d\n",T[index]);
}
}
}
int main()
{
Status curStatus;
SqBiTree tree;
InitBiTree(tree);
//printf("Empty:%d\n",BiTreeEmpty(tree));
CreateBiTree(tree);
//printf("Empty:%d\n",BiTreeEmpty(tree));
printf("Tree Depth = %d\n",BiTreeDepth(tree));
Position curPos = {3,2};
printf("position elem = %d\n",Value(tree,curPos));
printf("parent elem = %d\n",Parent(tree,5));
//PreOrderTraverse(tree,0);
//InOrderTraverse(tree,0);
PostOrderTraverse(tree,0);
return 0;
}