c语言顺序结构作业,二叉树的顺序结构C语言实现

顺序存储结构--将二叉树按层序依次存入数组中

已知一个节点在数组中序号为i,则该节点的

双亲节点序号为:((i+1)/2)-1

左孩子:         2*i+1

右孩子:         2*i+2

代码实现关键点:

1.创建二叉树CreateBiTree():按层次顺序输入二叉树中节点的值

1)对非空无双亲的非根节点的判断   if(i!=0&&T[(i+1)/2-1]==0&&T[i]!=0)

非根节点--i!=0;无双亲--T[(i+1)/2-1]=Nil;非空--T[i]=Nil

此种节点的存在不合理:除根节点外,其他非空节点都有双亲节点。如果出现 非根,非空,但又没有双亲的节点,

则该该节点不合法。

2.得到二叉树的深度BiTreeDepth

先得到节点数,然后利用二叉树性质2(深度为k的二叉树至多有(2^k)-1个节点)得到深度。

3.Assign()给处于位置(level,order)的节点赋值。(level,order)表示(层,层序),从左到右

因为二叉树第k层最多有2^(k-1)个节点,所以有对赋值节点位置越界的判断

if(level>BiTreeDepth(T)||order>(int)powl(2,level-1))

int pos = (int)powl(2,e.level-1)+e.order-2 ---将(level,order)转化为节点在数组的位置

两种不合法赋值判断:1).给叶子赋值,但是双亲为空;2).给双亲赋空值,但是其有叶子节点(非空)

1)---if(value!=Nil&&T[(pos+1)/2-1]==Nil)

2)---if(value==Nil&&(T[pos*2+1]!=Nil||T[pos*2+2]!=Nil))

3.RightSibling返回节点e的右兄弟,否则返回空

if(T[i]==e&&i%2!=0)---找到e,且i为奇数--左孩子,则其右兄弟为T[i+1]

4.三种遍历:先序,中序,后序

三者在代码上没有太大区别,只是反问局部根节点的顺序分别为:左根右、根左右、左右根

判断是否为左孩子:if(T[2*i+1]!=Nil)

判断是否为右孩子:if(T[2*i+2]!=Nil)

代码(站在巨人的肩膀上)

#include

#include

#include

#include

#define OK 1

#define ERROR 0

#define TRUE 1

#define FALSE 0

#define MAXSIZE 100

#define MAX_TREE_SIZE 100

typedef int Status;

typedef int TElemType;

typedef TElemType SqBiTree[MAX_TREE_SIZE];//将SqBiTree定义为元素TElemType的数组

typedef struct

{

int level,order;

}Position;

TElemType Nil = 0;//Nil表示无值,是object-c,Ruby,Lua中的关键字

//创建空树,此处树中每个节点都为0

Status InitBiTree(SqBiTree T)

{

for(int i = 0;i

{

T[i]=0;//The initial data of the tree node is zero

}

return OK;

}

//创建树,按层次顺序输入二叉树中节点的值

Status CreateBiTree(SqBiTree T)

{

int i=0;

if(NULL==T)

{

return ERROR;

}

printf("请按层顺序输入节点的值(整型),0表示空节点,输入0结束.节点树

while(i<20)

{

T[i]=i+1;

if(i!=0&&T[(i+1)/2-1]==0&&T[i]!=Nil)//二叉树中没有此内节点。非根节点--i!=0;无双亲--T[(i+1)/2-1]==Nil;非空节点--T[i]!=Nil

{

printf("出现非空的无双亲的非根节点%d\n",T[i]);

exit(ERROR);

}

i++;

}

while(i

{

T[i] = 0;

i++;

}

return OK;

}

//ClearBiTree将树的节点数据清零,相当于函数InitTree

#define ClearBiTree InitBiTree

//初始条件:二叉树存在

//操作结果:EmptyBiTree检查树是否为空,如果为空返回TRUE,否则返回FALSE

Status EmptyBiTree(SqBiTree T)

{

if(NULL==T)

{

return ERROR;

}

if(Nil==T[0]) //根节点为空,则树为空

{

return TRUE;

}

return FALSE;

}

//初始条件:二叉树存在

//操作结果:返回树的深度(层)

int BiTreeDepth(SqBiTree T)

{

if(NULL==T)

{

return ERROR;

}

int i,j=0;

for(i=MAX_TREE_SIZE-1;i>=0;i--)

{

if(T[i]!=Nil)

{

break;

}

}

i++; //节点数

while(i>=powl(2,j)) //二叉树性质:深度为k的二叉树至多有(2^k)-1个节点

{

j++;

}

return j;

}

//初始条件:二叉树存在

//操作结果:得到根节点,并用e返回根,返回OK;否则返回ERROR

Status Root(SqBiTree T,TElemType *e)

{

if(EmptyBiTree(T))

{

return ERROR;

}else

{

*e = T[0];

return OK;

}

}

//初始条件:二叉树存在

//操作结果:返回指定节点的值,没有则返回ERROR;Position(层,本层序号)确定节点位置

TElemType Value(SqBiTree T,Position e)

{

if(NULL==T)

{

return ERROR;

}

if(0==T[0])

{

return ERROR;

}

if(e.level>BiTreeDepth(T)||e.order>(int)powl(2,e.level-1))//节点不存在

{

return ERROR;

}

int pos = (int)powl(2,e.level-1)+e.order-2;//根据e确定节点在数组中的位置

return T[pos];

}

//初始条件:二叉树存在

//操作处理:给处于e的树T的节点赋值value,没有则返回ERROR

Status Assign(SqBiTree T,Position e,TElemType value)

{

if(NULL==T)

{

return ERROR;

}

if(e.level>BiTreeDepth(T)||e.order>(int)powl(2,e.level-1))//位置越界

{

return ERROR;

}

int pos = (int)powl(2,e.level-1)+e.order-2; //将Position转化为节点在数组的位置

if(value!=Nil&&T[(pos+1)/2-1]==Nil)//给叶子赋值,但是双亲为空

{

return ERROR;

}else if(value==Nil&&(T[pos*2+1]!=Nil||T[pos*2+2]!=Nil))//给双亲赋空值,但是有叶子节点(不空)

{

return ERROR;

}

T[pos] = value;

return OK;

}

//初始条件:二叉树存在

//操作处理:返回非根节点e的双亲节点,没有则返回“空”

TElemType Parent(SqBiTree T,TElemType e)

{

if(NULL == T)

{

return ERROR;

}

int i;

for(i=0;i

{

if(e==T[i])

{

return T[(i+1)/2-1];//找到则返回其双亲节点T[(i+1)/2-1]

}

}

return Nil; //没找到则返回空

}

//初始条件:二叉树存在

//操作处理:若e是树T的非叶节点,则返回它的左孩子,否则返回空

TElemType LeftChild(SqBiTree T,TElemType e)

{

if(NULL==T)

{

return ERROR;

}

int i;

for(i=0;i

{

if(e==T[i])

{

return T[i*2+1];//找到返回其左孩子

}

}

return Nil;

}

//初始条件:二叉树存在

//操作处理:返回节点e的右兄弟,否则返回空

TElemType RightSibling(SqBiTree T,TElemType e)

{

if(NULL==T)

{

return ERROR;

}

if(Nil==T[0])

{

return Nil;

}

int i;

for(i=0;i<=MAX_TREE_SIZE-1;i++)

{

if(T[i]==e&&i%2!=0)//找到e,且i为奇数--左孩子

return T[i+1];

}

return Nil;

}

//访问某个节点--打印节点值

Status visit(TElemType c)

{

printf("%d ",c);

return OK;

}

//先序遍历:被调函数

void PreTraverse(SqBiTree T,int i)

{

visit(T[i]); //访问根节点

if(T[2*i+1]!=Nil) //如果有左孩子,先访问左孩子

{

PreTraverse(T,2*i+1);

}

if(T[2*i+2]!=Nil)//如果有右孩子,后访问右孩子

{

PreTraverse(T,2*i+2);

}

}

//初始条件:二叉树存在

//操作处理:先序遍历树T

Status PreOrderTraverse(SqBiTree T)

{

if(!EmptyBiTree(T))

{

PreTraverse(T,0);

}

printf("\n");

return OK;

}

//中序遍历:被调函数。思路同PreTraverse

void InTraverse(SqBiTree T,int i)

{

if(T[i*2+1]!=Nil)

{

InTraverse(T,i*2+1);

}

visit(T[i]);

if(T[i*2+2]!=Nil)

{

InTraverse(T,i*2+2);

}

}

//初始条件:二叉树存在

//操作处理:中序遍历树T

Status InOrderTraverse(SqBiTree T)

{

if(!EmptyBiTree(T))

{

InTraverse(T,0);

}

printf("\n");

return OK;

}

int main()

{

SqBiTree T;

CreateBiTree(T);

/*返回树的深度*/

int depth =BiTreeDepth(T);

printf("深度:%d\n",depth);

/*返回特定位置的节点的值*/

printf("返回特定位置的节点值---输入节点位置:\n");

Position e;

scanf("%d %d",&e.level,&e.order);

TElemType value = Value(T,e);

printf("处于位置e的节点值为:%d\n",value);

/*给特定节点赋值*/

printf("给特定节点赋值---输入节点位置:\n");

Position pos;

scanf("%d %d",&pos.level,&pos.order);

Status sts = Assign(T,pos,4);

if(OK==sts)

{

printf("节点e被赋值为:%d\n",T[(int)powl(2,pos.level-1)+pos.order-2]);

}else

{

printf("赋值失败!\n");

}

/*返回双亲节点*/

printf("返回双亲节点---输入节点值:\n");

TElemType c;

scanf("%d",&c);

TElemType parent = Parent(T,c);

printf("双亲节点值为:%d\n",parent);

/*返回右兄弟*/

printf("返回右兄弟节点---输入节点值:\n");

TElemType d;

scanf("%d",&d);

TElemType rightsibling = RightSibling(T,d);

printf("右兄弟节点值为:%d\n",rightsibling);

/*先序遍历*/

PreOrderTraverse(T);

/*中序遍历*/

InOrderTraverse(T);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值