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

目录

(1)二叉树的数据结构

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

(3)求树的结点数

(4)求树的层数

(5)结点查找

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

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

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

(9)层次遍历算法

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

全部代码


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

(1)二叉树的数据结构

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

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

cs 复制代码
//前序序列建立二叉树
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)求树的结点数

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

(4)求树的层数

cs 复制代码
//求树的层数(递归)
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)结点查找

cs 复制代码
//查找结点,并说明它在第几层
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)前序遍历(递归算法和非递归算法)

cs 复制代码
//前序遍历(递归算法)
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)中序遍历(递归算法和非递归算法)

cs 复制代码
//中序遍历(递归算法)
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)后序遍历(递归算法和非递归算法)

cs 复制代码
//后序遍历(递归算法)
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)层次遍历算法

cs 复制代码
//层次遍历
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)遍历过程中借助的栈和队列算法

cs 复制代码
//(循环)队列和栈的数据结构
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##。

cs 复制代码
#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;
}

输出:

cs 复制代码
输入二叉树的前序序列,#代表空子树:
ABD##E##C##
二叉树创建成功!
二叉树的前序遍历序列是:ABDEC
二叉树的中序遍历序列是:DBEAC
二叉树的后序遍历序列是:DEBCA
二叉树的层次遍历序列是:ABCDE
查找成功!元素在第3层
二叉树的元素个数是:5
二叉树的深度是:3
二叉树的前序遍历序列(非递归)是:ABDEC
二叉树的中序遍历序列(非递归)是:DBEAC
二叉树的后序遍历序列(非递归)是:DEBCA
相关推荐
weixin_3077791334 分钟前
PySpark实现ABC_manage_channel逻辑
开发语言·python·spark
??? Meggie2 小时前
【Python】保持Selenium稳定爬取的方法(防检测策略)
开发语言·python·selenium
酷爱码3 小时前
如何通过python连接hive,并对里面的表进行增删改查操作
开发语言·hive·python
画个大饼3 小时前
Go语言实战:快速搭建完整的用户认证系统
开发语言·后端·golang
喵先生!5 小时前
C++中的vector和list的区别与适用场景
开发语言·c++
Thomas_YXQ5 小时前
Unity3D Lua集成技术指南
java·开发语言·驱动开发·junit·全文检索·lua·unity3d
xMathematics5 小时前
计算机图形学实践:结合Qt和OpenGL实现绘制彩色三角形
开发语言·c++·qt·计算机图形学·cmake·opengl
yuanManGan8 小时前
C++入门小馆: 深入了解STLlist
开发语言·c++
北极的企鹅888 小时前
XML内容解析成实体类
xml·java·开发语言
梁下轻语的秋缘8 小时前
每日c/c++题 备战蓝桥杯(P1049 [NOIP 2001 普及组] 装箱问题)
c语言·c++·学习·蓝桥杯