34.二叉链树的C语言实现

目录

(1)二叉树的数据结构

(2)以前序序列建立二叉树

(3)求树的结点数

(4)求树的层数

(5)结点查找

(6)前序遍历(递归算法和非递归算法)

(7)中序遍历(递归算法和非递归算法)

(8)后序遍历(递归算法和非递归算法)

(9)层次遍历算法

(10)遍历过程中借助的栈和队列算法

全部代码


包含二叉链树的建立,计数,查找,各种遍历。

(1)二叉树的数据结构

//二叉链树的结构体定义
typedef struct BiTNode{
    ElemType data;  //数据域
    BiTNode *lchild;  //指向左子树根节点的指针
	BiTNode *rchild;  //指向右子树根节点的指针
}BiTNode, *BiTree;

(2)以前序序列建立二叉树

//前序序列建立二叉树
void CreateBiTree(BiTree &T){
    ElemType ch;
    scanf("%c", &ch);
    if (ch == '#')
        T = NULL;  //保证是叶结点
    else{
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;  //生成结点
        CreateBiTree(T->lchild);  //构造左子树
        CreateBiTree(T->rchild);  //构造右子树    
    }
}

(3)求树的结点数

//求树的结点数(递归)
int Number_Node(BiTree T){
    if(T==NULL)
        return 0;
    else{
        return Number_Node(T->lchild) + Number_Node(T->rchild) + 1;
    }
}

(4)求树的层数

//求树的层数(递归)
int Depth(BiTree T){
    if(T==NULL)
        return 0;
    else{
        return (Depth(T->lchild) >= Depth(T->rchild)) ? Depth(T->lchild) + 1 : Depth(T->rchild) + 1;
    }
}

(5)结点查找

//查找结点,并说明它在第几层
BiTree Search(BiTree T, char a, int level){
    if(T == NULL)
        return NULL;
    else if(T->data == a){
        printf("查找成功!元素在第%d层\n",level);
        return T;
    }
    else{
        Search(T->lchild, a, level + 1);
        Search(T->rchild, a, level + 1);
    }
}

(6)前序遍历(递归算法和非递归算法)

//前序遍历(递归算法)
void PreOrderTraverse(BiTree T){
	if (T!=NULL){
		printf("%c", T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}

//前序遍历(非递归算法)
void PreOrderTraverse2(BiTree T){
    BiTree p = T; //p是遍历指针
    Sqstack S;
    InitStack(S);
    while(p != NULL|| !IsStackEmpty(S)){
        if(p){
            printf("%c", p->data);
            InsertSqstack(S, p);
            p = p->lchild;
        }
        else{
            p = DeleteSqstack(S, p);
            p = p->rchild;
        }
    }
}

(7)中序遍历(递归算法和非递归算法)

//中序遍历(递归算法)
void InOrderTraverse(BiTree T){
	if (T!=NULL){
		InOrderTraverse(T->lchild);
        printf("%c", T->data);
		InOrderTraverse(T->rchild);
	}
}

//中序遍历(非递归算法)
void InOrderTraverse2(BiTree T){
    BiTree p = T; //p是遍历指针
    Sqstack S;
    InitStack(S);
    while(p||!IsStackEmpty(S)){
        if(p){
            InsertSqstack(S, p);
            p = p->lchild;
        }
        else{
            p = DeleteSqstack(S, p);
            printf("%c", p->data);
            p = p->rchild;
        }
    }
}

(8)后序遍历(递归算法和非递归算法)

//后序遍历(递归算法)
void PostOrderTraverse(BiTree T){
	if (T!=NULL){
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
        printf("%c", T->data);
	}
}

//后序遍历(非递归算法)
void PostOrderTraverse2(BiTree T){
    Sqstack S;
    InitStack(S);
    BiTree p = T;
    BiTree r = NULL;
    while(p||!IsStackEmpty(S)){
        if(p){
            InsertSqstack(S, p);
            p = p->lchild;
        }
        else{
            p = S.data[S.top];  //读栈顶元素(但不出栈)
            if(p->rchild&&p->rchild!=r){
                p = p->rchild;
            }
            else{
                p = DeleteSqstack(S, p);
                printf("%c", p->data);
                r = p;
                p = NULL;
            }
        }
    }
}

(9)层次遍历算法

//层次遍历
void LevelOrder(BiTree T){
    Queue q;
    InitQueue(q);
    BiTree p = T;
    InsertQueue(q, p);
    while(!IsQueueEmpty(q)){
        p = DeleteQueue(q, p);
        printf("%c", p->data);
        if(p->lchild!=NULL)
            InsertQueue(q, p->lchild);
        if(p->rchild!=NULL)
            InsertQueue(q, p->rchild);
    }
}

(10)遍历过程中借助的栈和队列算法

//(循环)队列和栈的数据结构
typedef struct Queue{
	BiTree data[MAXSIZE];
    int front, rear;  //头尾指针,队头指针指向第一个元素,队尾指针指向队尾元素的下一个元素
    int tag;
}Queue;
typedef struct Sqstack{
    BiTree data[MAXSIZE];
    int top;  //栈顶指针指向栈顶元素
}Sqstack;

//初始化
int InitQueue(Queue &a){
    a.front = 0;
    a.rear = 0;
    a.tag = 0;  //初始队列是空
    return 1;
}
int InitStack(Sqstack &a){
    a.top = -1;  //初始栈顶指针是-1
    return 1;
}

//判断栈和队列是否为空
bool IsStackEmpty(Sqstack S){
    if(S.top ==-1)
        return true;
    else
        return false;
}
bool IsQueueEmpty(Queue q){
    if(q.tag == 0 && q.front==q.rear)
        return true;
    else
        return false;
}

//插入
int InsertQueue(Queue &a, BiTree x){
    if(a.front == a.rear && a.tag == 1){
        printf("当前队列已满!");
        return 0;
    }
    else{
        a.data[a.rear] = x;
        a.tag = 1;  //插入队列tag置1
        a.rear = (a.rear + 1) % MAXSIZE;
        return 1;
    }  
}
int InsertSqstack(Sqstack &a, BiTree x){
    if(a.top == MAXSIZE-1){
        printf("当前栈已满!");
        return 0;
    }
    else{
        a.top = a.top + 1;
        a.data[a.top] = x;
        return 1;
    } 
}

//删除
BiTree DeleteQueue(Queue &a,BiTree x){
    if(a.front == a.rear && a.tag == 0){
        printf("当前队列已空!");
    }
    else{
        x = a.data[a.front];
        a.tag = 0;  //删除队列tag置0
        a.front = (a.front + 1) % MAXSIZE;  //front指针+1
        return x;
    }  
}
BiTree DeleteSqstack(Sqstack &a, BiTree x){
    if(a.top == -1){
        printf("当前栈已空!");
    }
    else{
        x = a.data[a.top];
        a.top = a.top - 1;
        return x;
    }  
}

全部代码

本次验证的二叉树如下图:

注意:输入的是扩展二叉树,也就是要告诉计算机什么是叶结点,否则将一直递归,当输入“#”时,指针指向NULL,说明是叶结点。例如对于上图,输入的是ABD##E##C##。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100
#define ElemType char

//二叉链树的结构体定义
typedef struct BiTNode{
    ElemType data;  //数据域
    BiTNode *lchild;  //指向左子树根节点的指针
	BiTNode *rchild;  //指向右子树根节点的指针
}BiTNode, *BiTree;

//(循环)队列和栈的数据结构
typedef struct Queue{
	BiTree data[MAXSIZE];
    int front, rear;  //头尾指针,队头指针指向第一个元素,队尾指针指向队尾元素的下一个元素
    int tag;
}Queue;
typedef struct Sqstack{
    BiTree data[MAXSIZE];
    int top;  //栈顶指针指向栈顶元素
}Sqstack;

//初始化
int InitQueue(Queue &a){
    a.front = 0;
    a.rear = 0;
    a.tag = 0;  //初始队列是空
    return 1;
}
int InitStack(Sqstack &a){
    a.top = -1;  //初始栈顶指针是-1
    return 1;
}

//判断栈和队列是否为空
bool IsStackEmpty(Sqstack S){
    if(S.top ==-1)
        return true;
    else
        return false;
}
bool IsQueueEmpty(Queue q){
    if(q.tag == 0 && q.front==q.rear)
        return true;
    else
        return false;
}

//插入
int InsertQueue(Queue &a, BiTree x){
    if(a.front == a.rear && a.tag == 1){
        printf("当前队列已满!");
        return 0;
    }
    else{
        a.data[a.rear] = x;
        a.tag = 1;  //插入队列tag置1
        a.rear = (a.rear + 1) % MAXSIZE;
        return 1;
    }  
}
int InsertSqstack(Sqstack &a, BiTree x){
    if(a.top == MAXSIZE-1){
        printf("当前栈已满!");
        return 0;
    }
    else{
        a.top = a.top + 1;
        a.data[a.top] = x;
        return 1;
    } 
}

//删除
BiTree DeleteQueue(Queue &a,BiTree x){
    if(a.front == a.rear && a.tag == 0){
        printf("当前队列已空!");
    }
    else{
        x = a.data[a.front];
        a.tag = 0;  //删除队列tag置0
        a.front = (a.front + 1) % MAXSIZE;  //front指针+1
        return x;
    }  
}
BiTree DeleteSqstack(Sqstack &a, BiTree x){
    if(a.top == -1){
        printf("当前栈已空!");
    }
    else{
        x = a.data[a.top];
        a.top = a.top - 1;
        return x;
    }  
}

//前序序列建立二叉树
void CreateBiTree(BiTree &T){
    ElemType ch;
    scanf("%c", &ch);
    if (ch == '#')
        T = NULL;  //保证是叶结点
    else{
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;  //生成结点
        CreateBiTree(T->lchild);  //构造左子树
        CreateBiTree(T->rchild);  //构造右子树    
    }
}

//求树的结点数(递归)
int Number_Node(BiTree T){
    if(T==NULL)
        return 0;
    else{
        return Number_Node(T->lchild) + Number_Node(T->rchild) + 1;
    }
}

//求树的层数(递归)
int Depth(BiTree T){
    if(T==NULL)
        return 0;
    else{
        return (Depth(T->lchild) >= Depth(T->rchild)) ? Depth(T->lchild) + 1 : Depth(T->rchild) + 1;
    }
}

//查找结点,并说明它在第几层
BiTree Search(BiTree T, char a, int level){
    if(T == NULL)
        return NULL;
    else if(T->data == a){
        printf("查找成功!元素在第%d层\n",level);
        return T;
    }
    else{
        Search(T->lchild, a, level + 1);
        Search(T->rchild, a, level + 1);
    }
}

//前序遍历(递归算法)
void PreOrderTraverse(BiTree T){
	if (T!=NULL){
		printf("%c", T->data);
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}
//前序遍历(非递归算法)
void PreOrderTraverse2(BiTree T){
    BiTree p = T; //p是遍历指针
    Sqstack S;
    InitStack(S);
    while(p != NULL|| !IsStackEmpty(S)){
        if(p){
            printf("%c", p->data);
            InsertSqstack(S, p);
            p = p->lchild;
        }
        else{
            p = DeleteSqstack(S, p);
            p = p->rchild;
        }
    }
}

//中序遍历(递归算法)
void InOrderTraverse(BiTree T){
	if (T!=NULL){
		InOrderTraverse(T->lchild);
        printf("%c", T->data);
		InOrderTraverse(T->rchild);
	}
}
//中序遍历(非递归算法)
void InOrderTraverse2(BiTree T){
    BiTree p = T; //p是遍历指针
    Sqstack S;
    InitStack(S);
    while(p||!IsStackEmpty(S)){
        if(p){
            InsertSqstack(S, p);
            p = p->lchild;
        }
        else{
            p = DeleteSqstack(S, p);
            printf("%c", p->data);
            p = p->rchild;
        }
    }
}

//后序遍历(递归算法)
void PostOrderTraverse(BiTree T){
	if (T!=NULL){
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
        printf("%c", T->data);
	}
}
//后序遍历(非递归算法)
void PostOrderTraverse2(BiTree T){
    Sqstack S;
    InitStack(S);
    BiTree p = T;
    BiTree r = NULL;
    while(p||!IsStackEmpty(S)){
        if(p){
            InsertSqstack(S, p);
            p = p->lchild;
        }
        else{
            p = S.data[S.top];  //读栈顶元素(但不出栈)
            if(p->rchild&&p->rchild!=r){
                p = p->rchild;
            }
            else{
                p = DeleteSqstack(S, p);
                printf("%c", p->data);
                r = p;
                p = NULL;
            }
        }
    }
}

//层次遍历
void LevelOrder(BiTree T){
    Queue q;
    InitQueue(q);
    BiTree p = T;
    InsertQueue(q, p);
    while(!IsQueueEmpty(q)){
        p = DeleteQueue(q, p);
        printf("%c", p->data);
        if(p->lchild!=NULL)
            InsertQueue(q, p->lchild);
        if(p->rchild!=NULL)
            InsertQueue(q, p->rchild);
    }
}

int main(){
    BiTree T;
    printf("输入二叉树的前序序列,#代表空子树:\n");
    CreateBiTree(T);
    printf("二叉树创建成功!\n");
    printf("二叉树的前序遍历序列是:");
    PreOrderTraverse(T);
    printf("\n");
    printf("二叉树的中序遍历序列是:");
    InOrderTraverse(T);
    printf("\n");
    printf("二叉树的后序遍历序列是:");
    PostOrderTraverse(T);
    printf("\n");
    printf("二叉树的层次遍历序列是:");
    LevelOrder(T);
    printf("\n");
    Search(T, 'D', 1);  //第1个结点在第1层
    printf("二叉树的元素个数是:%d\n", Number_Node(T));
    printf("二叉树的深度是:%d\n", Depth(T));

    printf("二叉树的前序遍历序列(非递归)是:");
    PreOrderTraverse2(T);
    printf("\n");
    printf("二叉树的中序遍历序列(非递归)是:");
    InOrderTraverse2(T);
    printf("\n");
    printf("二叉树的后序遍历序列(非递归)是:");
    PostOrderTraverse2(T);
    printf("\n");
    return 0;
}

输出:

输入二叉树的前序序列,#代表空子树:
ABD##E##C##
二叉树创建成功!
二叉树的前序遍历序列是:ABDEC
二叉树的中序遍历序列是:DBEAC
二叉树的后序遍历序列是:DEBCA
二叉树的层次遍历序列是:ABCDE
查找成功!元素在第3层
二叉树的元素个数是:5
二叉树的深度是:3
二叉树的前序遍历序列(非递归)是:ABDEC
二叉树的中序遍历序列(非递归)是:DBEAC
二叉树的后序遍历序列(非递归)是:DEBCA
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北京地铁1号线

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值