顺序二叉树的实现

树是常见数据结构
二叉树是指点度最多只有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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值