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
相关推荐
SRY122404192 小时前
javaSE面试题
java·开发语言·面试
lb36363636363 小时前
介绍一下数组(c基础)(详细版)
c语言
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言
ZIM学编程3 小时前
Java基础Day-Sixteen
java·开发语言·windows
我不是星海3 小时前
1.集合体系补充(1)
java·数据结构
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
一丝晨光4 小时前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
代码小鑫4 小时前
A027-基于Spring Boot的农事管理系统
java·开发语言·数据库·spring boot·后端·毕业设计