c语言实现二叉树存储与访问

 

#include <stdio.h>
#include <stdlib.h>

/*二叉树顺序存储结构*/
#define MAXSIZE 100
typedef char SqBiTree[MAXSIZE];//以数组的形式存储
SqBiTree bt;

/*二叉树链式存储结构*/
typedef struct BiTNode{
    char data;//数据域
    struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode,*BiTree;//初始化树的函数

/*栈的相关定义*/
#define STACKINITSIZE 50//栈初始空间大小
#define INCREASEMENT 50//栈空间大小的增量
typedef struct SqStack
{//定义顺序栈结构
	BiTNode *base;//栈底指针
	BiTNode *top;//栈顶指针
	int stacksize;//顺序栈空间大小
}SqStack;

int InitStack(SqStack *S)
{//建立一个空栈,建立成功,返回1,失败,返回0
	S->base = (BiTNode*)malloc(STACKINITSIZE * sizeof(BiTNode));
	if(!S->base)
		return 0;
	S->top = S->base = 0;
	S->stacksize = STACKINITSIZE;
	return 1;
}

int Push(SqStack *S,BiTNode e)
{//进栈操作
	if(S->top - S->base >= S->stacksize)
	{
		S->base = (BiTNode*)realloc(S->base,(STACKINITSIZE + INCREASEMENT) * sizeof(BiTNode));
		if(!S->base)
			return 0;
		S->stacksize = 30;
	}
	*S->top = e;
	S->top ++;
	return 1;
}

int Pop(SqStack *S,BiTNode *e)
{//出栈操作,若栈为空,则返回0;栈不为空,则返回1
	if(S->base == S->top == 0)
		return 0;
	e = --S->top;
	return 1;
}

/*用链式方式来构造二叉树*/
void CreateBiTreeLink(BiTree *T){
    (*T)=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->data='F';
    (*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->lchild->data='B';
    (*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->lchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->lchild->lchild->data='A';
    (*T)->lchild->lchild->lchild=NULL;
    (*T)->lchild->lchild->rchild=NULL;
    (*T)->lchild->rchild->data='D';
    (*T)->lchild->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->lchild->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->lchild->rchild->lchild->data='C';
    (*T)->lchild->rchild->rchild->data='E';
    (*T)->lchild->rchild->lchild->lchild=NULL;
    (*T)->lchild->rchild->lchild->rchild=NULL;
    (*T)->lchild->rchild->rchild->lchild=NULL;
    (*T)->lchild->rchild->rchild->rchild=NULL;
    (*T)->rchild->data='G';
    (*T)->rchild->rchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->rchild->lchild=NULL;
    (*T)->rchild->rchild->data='I';
    (*T)->rchild->rchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
    (*T)->rchild->rchild->rchild=NULL;
    (*T)->rchild->rchild->lchild->data='H';
    (*T)->rchild->rchild->lchild->lchild=NULL;
    (*T)->rchild->rchild->lchild->rchild=NULL;
}//模拟操作结点元素的函数,输出结点本身的数值

/*用顺序存储方式构造二叉树*/
void CreateBiTreeOrder(BiTNode *T)
{//此处是二叉树的前序遍历方式创建,如果要使用中序或者后序的方式建立二叉树,只需将生成结点和构造左右子树的顺序改变即可
    char ch;
    scanf("%c",&ch);//将从终端输入的字符传进ch中
    if(ch=='#')//#表示空结点
        T=NULL;//遇到#,T也赋值为空
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));//否则生成一个空间
        if(!T)//若无法生成则退出
            exit(-1);
        T->data=ch;//否则将ch的值赋值给T空间的data域
        CreateBiTreeOrder(T->lchild);//用递归指向T的左孩子,重复操作
        CreateBiTreeOrder(T->rchild);//左孩子全赋值完后到右孩子
    }//先序读取数据,根左右
}


/*递归后序遍历*/
void PostOrderTraverse(BiTNode *T){
    if (T) {
        PostOrderTraverse(T->lchild);//遍历左孩子
        PostOrderTraverse(T->rchild);//遍历右孩子
        printf("%c ",T->data);//访问根节点
    }//如果结点为空,返回上一层
}

/*非递归中序遍历*/
int InOrderTraverse(BiTNode *T){
    BiTNode *p,*e;          //p指针用于代替T进行操作,e指针用于返回出栈的值
    SqStack S;        //S为空栈
    InitStack(&S);     //初始化栈S
    p=T;    //p指向T的位置
    while(p!=0||S.top!=0)   //p结点不为空或栈不空时执行循环操作
    {
        if(p!=0)          //栈空但p结点不空
        {
            Push(&S,*p);     //p结点入栈
            p=p->lchild;    //p指针指向其左孩子
        }
        else       //p结点为空但栈不空
        {
            Pop(&S,e);         //弹出栈中结点并返回其值
            printf("%c ",e->data);          //打印返回结点的数据
            p=e->rchild;         //p指针指向根结点的右孩子
        }
    }//while 一直到p指针空且栈空
    return 1;
}


int main() {
    printf("BiTree start:\n");     //链式二叉树遍历开始
    BiTree Tree;
    CreateBiTreeLink(&Tree);      //生成链式二叉树
    printf("PostOrderTraverse:\n");      //打印递归后序遍历结果
    PostOrderTraverse(Tree);
    printf("\nInOrderTraverse:\n");      //打印非递归中序遍历结果
    InOrderTraverse(Tree);

    printf("SqBiTree start:\n");        //顺序二叉树遍历开始
    BiTNode T;
    printf("scanf PreOrderTraverse:");        //先序读入FBA##DC##E##G#IH###
    CreateBiTreeOrder(&T);            //构造二叉树
    printf("printf PostOrderTraverse:\n");       //打印递归后序遍历结果
    PostOrderTraverse(&T);
    printf("printf InOrderTraverse:\n");      //打印非递归中序遍历结果
    InOrderTraverse(&T);
}

实验完成后老师点评:

读取可以使用双亲存储或者孩子链表存储不用每一个都手动输入。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值