在实现二叉树的顺序存储的过程中,遇到了一些问题,现记录如下:
#include<stdio.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_SIZE 100/*定义树的最大节点数*/
typedef int status;
typedef int elemtype;
typedef struct position {
int level;
int order;
} position;
typedef elemtype sqbitree[MAXSIZE];
elemtype null=0;/*设0表示空*/
status visit(elemtype c) {
printf("%d ",c);
return OK;
}
status initbitree(sqbitree T) {
int i=0;
for(i=0; i<MAX_TREE_SIZE; i++)
T[i]=null;/*初始化时将所有节点置为空*/
return OK;
}
/*创建二叉树*/
status createbitree(sqbitree T) {
int i=0;
printf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤%d:\n",MAX_TREE_SIZE);
while(i<10) {
T[i]=i+1;
/*T[(i+1)/2-1]是T[i]的双亲节点*/
if(i&&!T[(i+1)/2-1]&&T[i]) {
printf("产生了没有双亲节点的新节点\n");
return ERROR;
}
i++;
}
/*其余节点置空*/
while(i<MAX_TREE_SIZE) {
T[i]=null;
i++;
}
return OK;
}
/*判断二叉树为空*/
status emptybitree(sqbitree T) {
if(!T[0])
return TRUE;
else
return FALSE;
}
/*求二叉树深度*/
status depthbitree(sqbitree T) {
int i,j=-1;
/*从最后一个节点开始,找到第一个不为空的节点*/
for(i=MAX_TREE_SIZE-1; i>=0; i--)
if(T[i])
break;
i++;
do {
j++;
} while(i>=pow(2,j));
return j;
}
/*返回二叉树的根节点*/
status root(sqbitree T,elemtype *e) {
if(emptybitree(T)) {
printf("二叉树为空\n");
return ERROR;
} else {
*e=T[0];
return OK;
}
}
/*给二叉树中第e层序对节点赋新值value*/
status refresh(sqbitree T,position e,elemtype value) {
/*将e转换成数组下标,这个公式画出示意图很容易就能理解*/
int i=(int)(pow(2,e.level-1)+e.order-2);
/*情况一:给叶子赋空但双亲为空,返回ERROR*/
if(!value&&!T[(i+1)/2-1])
return ERROR;
/*情况二:给双亲赋空但叶子不为空,返回ERROR*/
if(!value&&T[i*2+1]||T[i*2+2])
return ERROR;
T[i]=value;
return OK;
}
/*返回一个节点的左孩子*/
elemtype leftchild(sqbitree T,elemtype e){
int i=0;
if(!T[0])
return ERROR;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e)
return T[i*2+1];
}
return ERROR;
}
/*返回一个节点的右孩子*/
elemtype rightchild(sqbitree T,elemtype e) {
int i=0;
if(!T[0]) {
printf("空树\n");
return null;
}
for(i=0; i<MAX_TREE_SIZE; i++) {
if(T[i]==e)
return T[i*2+2];
}
return ERROR;/*没找到*/
}
/*返回一个节点的左兄弟,若e是T的左孩子或无左兄弟,则返回"空"*/
elemtype leftslibing(sqbitree T,elemtype e) {
int i=0;
if(!T[0]) {
printf("空树\n");
return null;
}
for(i=0; i<MAX_TREE_SIZE; i++)
if(T[i]==e&&i%2==0)/*i为偶数,*则为右子孙,减一即可得到左兄弟*//*此外,这个地方写i%2==0h和!i%2的结果不一样,正在思考原因*/
return T[i-1];
return null;
}
/*回一个节点的右兄弟,若e是T的左孩子或无左兄弟,则返回"空"*/
elemtype rightslibing(sqbitree T,elemtype e) {
int i=0;
if(!T[0]) {
printf("空树\n");
return null;
}
for(i=0; i<MAX_TREE_SIZE; i++) {
if(T[i]==e&&i%2)/*i为奇数,*则为左子孙,减一即可得到右兄弟*/
return T[i+1];
}
return null;
}
/*返回双亲*/
elemtype parent(sqbitree T,elemtype e){
int i=0;
for(i=0;i<MAX_TREE_SIZE;i++){
if(T[i]==e)
return T[(i+1)/2-1];
}
}
/*遍历二叉树*/
/*前序遍历*/
status preorder(sqbitree T,int i){
visit(T[i]);/*先访问根节点,再递归访问左子树和右子树*/
if(T[2*i+1])
preorder(T,2*i+1);
if(T[2*i+2])
preorder(T,2*i+2);
}
status pretraverse(sqbitree T){
if(emptybitree(T))
return ERROR;
else{
preorder(T,0);/*从0开始递归*/
printf("\n");
}
return OK;
}
/*中序遍历二叉树*/
void InTraverse(sqbitree T,int e)
{
if(T[2*e+1]!=null) /* 左子树不空 */
InTraverse(T,2*e+1);
visit(T[e]);
if(T[2*e+2]!=null) /* 右子树不空 */
InTraverse(T,2*e+2);
}
status InOrderTraverse(sqbitree T)
{
if(!emptybitree(T)) /* 树不空 */
InTraverse(T,0);
printf("\n");
return OK;
}
/*后序遍历二叉树*/
status lastorder(sqbitree T,int i){
if(T[2*i+1])
lastorder(T,2*i+1);
if(T[2*i+2])
lastorder(T,2*i+2);
visit(T[i]);
}
status lasttraverse(sqbitree T){
if(emptybitree(T))
return ERROR;
else{
lastorder(T,0);
}
printf("\n");
}
int main(void) {
status i;
position p;
elemtype e;
sqbitree T;
initbitree(T);
createbitree(T);
printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",emptybitree(T),depthbitree(T));
printf("对二叉树做前序遍历:");
pretraverse(T);
printf("对二叉树做中序遍历:");
InOrderTraverse(T);
printf("对二叉树做后序遍历:");
lasttraverse(T);
e=50;
printf("修改层序为3,本层序号为2的节点的值,输入新值为%d\n",e);
p.level=3;
p.order=2;
refresh(T,p,50);
printf("对二叉树做前序遍历:");
pretraverse(T);
printf("节点50的双亲为%d,左右孩子分别为%d %d,左右兄弟为%d %d\n",parent(T,e),leftchild(T,e),rightchild(T,e),leftslibing(T,e),rightslibing(T,e));
initbitree(T);
printf("清空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",emptybitree(T),depthbitree(T));
root(T,&e);
}