数据结构实验:实现二叉树的各种基本运算的算法

实现二叉树的各种基本运算的算法

题目描述

编写二个程序biree.cpp,实现二叉树的基本运算,并在此基础上设计、exp7-1.cpp 完成以下功能。

(1)由如图7.1所示的二叉树创建对应的二叉链存储结构6,该二叉树的括号表示串为"A(B(D,E(H(J,K(1.MN))))CFGD))"

(2)输出二叉树b。

(3)输出'H'结点的左、右孩子结点值。

(4)输出二叉树6的高度。

(5)释放二叉树b。
算法如下:

btree.cpp程序,其中包含如下函数。

CreateBTree(BTNode*&b,char *str):由括号表示串 str创建二叉链6。

· FindNode(BTNode *b,ElemType x):返回 data 域为x的结点指针

·LchildNode(BTNode*p):返回户结点的左孩子结点指针。

·RchildNode(BTNode*p):返回户结点的右孩子结点指针

·BTHeight(BTNode *b):返回二叉树b的高度。

·DispBTree(BTNode*b):以括号表示法输出二叉树6

·DestroyBTree(BTNode*&b):释放二叉树b的所有结点。

运行代码

btree.cpp
cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define MaxSize 100
typedef char ElenType;

// 定义二叉树节点结构体
typedef struct BiTNode {
    ElenType data;
    struct BiTNode* lchild;
    struct BiTNode* rchild;
} BTNode;

// 创建二叉树函数
void CreateBTree(BTNode** b, const char* str) {
    // 创建一个栈用于存储节点
    BTNode* St[MaxSize];
    int top = -1;
    int k = 0;
    int j = 0;
    char ch;
    // 初始化二叉树为空
    *b = NULL;
    ch = str[j];
    BTNode* p = NULL; // 在这里初始化 p
    while (ch != '\0') {
        switch (ch) {
            // 遇到左括号
        case '(':
            top++;
            St[top] = p;
            k = 1;
            break;
            // 遇到逗号
        case ',':
            k = 2;
            break;
            // 遇到右括号
        case ')':
            top--;
            break;
        default:
            // 分配新节点内存
            p = (BTNode*)malloc(sizeof(BTNode));
            p->data = ch;
            p->lchild = p->rchild = NULL;
            if (*b == NULL) {
                // 如果是根节点
                *b = p;
            }
            else {
                // 根据标志 k 判断连接左子树或右子树
                if (k == 1) {
                    St[top]->lchild = p;
                }
                else {
                    St[top]->rchild = p;
                }
            }
            break;
        }
        j++;
        ch = str[j];
    }
}

// 销毁二叉树函数
void DestroyBTree(BTNode** b) {
    if (*b != NULL) {
        // 先销毁左子树
        DestroyBTree(&((*b)->lchild));
        // 再销毁右子树
        DestroyBTree(&((*b)->rchild));
        // 释放当前节点内存
        free(*b);
        // 将当前节点置为空指针
        *b = NULL;
    }
}
// 查找值为 x 的节点函数
BTNode* FindNode(BTNode* b, ElenType x) {
    BTNode* p;
    if (b == NULL) {
        return NULL;
    }
    else if (b->data == x) {
        return b;
    }
    else {
        // 在左子树中查找
        p = FindNode(b->lchild, x);
        if (p != NULL) {
            return p;
        }
        else {
            // 在右子树中查找
            return FindNode(b->rchild, x);
        }
    }
}

// 返回节点 p 的左孩子节点指针函数
BTNode* LchildNode(BTNode* p) {
    return p->lchild;
}
// 返回节点 p 的右孩子节点指针函数
BTNode* RchildNode(BTNode* p) {
    return p->rchild;
}
// 求二叉树高度函数
int BiTreeHeight(BTNode* b) {
    int lchildh, rchildh;
    if (b == NULL) {
        return 0;
    }
    // 递归求左子树高度
    lchildh = BiTreeHeight(b->lchild);
    // 递归求右子树高度
    rchildh = BiTreeHeight(b->rchild);
    // 返回较大子树高度加一
    return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1);
}

// 以括号表示法输出二叉树函数
void DispBTree(BTNode* b) {
    if (b != NULL) {
        // 输出当前节点数据
        printf("%c", b->data);
        if (b->lchild != NULL || b->rchild != NULL) {
            // 有子树时输出左括号
            printf("(");
            // 递归输出左子树
            DispBTree(b->lchild);
            if (b->rchild != NULL) {
                // 有右子树时输出逗号
                printf(",");
            }
            // 递归输出右子树
            DispBTree(b->rchild);
            // 有子树时输出右括号
            printf(")");
        }
    }
}
excp7-1.cpp
cpp 复制代码
#include <stdio.h>
#include "btree.cpp"
int main() {
    BTNode* b = NULL;
    BTNode* p = NULL;
    BTNode* lp = NULL;
    BTNode* rp = NULL;
    printf("二叉树的基本运算如下:\n");
    printf("(1)创建二叉树\n");
    CreateBTree(&b, "A(B(D,E(H(J,K(L,M)))),C(F,G(I)))");
    printf("(2)输出二叉树:");
    DispBTree(b);
    printf("\n");
    printf("(3)查找结点:");
    p = FindNode(b, 'H');
    if (p == NULL) {
        printf("未找到指定节点");
    }
    else {
        lp = LchildNode(p);
        if (lp != NULL) {
            printf("左孩子为%c ", lp->data);
        }
        else {
            printf("无左孩子");
        }
        rp = RchildNode(p);
        if (rp != NULL) {
            printf("右孩子为%c", rp->data);
        }
        else {
            printf("无右孩子");
        }
    }
    printf("\n");
    printf("(4)二叉树 b 的高度:%d\n", BiTreeHeight(b));
    printf("(5)释放二叉树 b\n");
    DestroyBTree(&b);
    return 0;
}

代码思路

  1. CreateBTree函数:根据给定的字符串创建二叉树。

    • 遇到右括号时,弹出栈顶元素。
    • 遇到逗号时,设置标志k为 2,表示接下来的节点为右子树节点。
    • 遇到左括号时,将当前节点压入栈中,并设置标志k为 1,表示接下来的节点为左子树节点。
    • 遇到普通字符时,创建新节点,并根据栈的状态和标志k确定将新节点连接到父节点的左子树或右子树。
    • 通过遍历输入字符串,根据不同的字符(左括号、逗号、右括号和普通字符)进行不同的操作。
    • 使用栈St来辅助创建二叉树,栈中存储二叉树节点指针。
  2. DestroyBTree函数:销毁二叉树,释放所有节点的内存。采用递归的方式,先销毁左子树,再销毁右子树,最后释放当前节点的内存,并将当前节点指针置为NULL

  3. FindNode函数:在二叉树中查找值为x的节点。

    • 否则,先在左子树中递归查找,如果左子树中未找到,则在右子树中递归查找。
    • 如果当前节点的数据等于x,则返回当前节点指针。
    • 如果二叉树为空,则返回NULL
  4. LchildNodeRchildNode函:分别返回给定节点的左孩子节点指针和右孩子节点指。

    直接返回节点的左孩子或右孩子指针。

  5. BiTreeHeight函数:求二叉树的高度。

    • 递归求左子树高度和右子树高度,然后返回较大子树高度加一。
    • 如果二叉树为空,则高度为 0。
  6. DispBTree函数:以括号表示法输出二叉树。

    • 最后输出右括号。
    • 如果当前节点有右子树,则在输出左子树后输出逗号,再递归输出右子树。
    • 如果当前节点有子树,则输出左括号,然后递归输出左子树。
    • 如果当前节点不为空,先输出当前节点的数据。
相关推荐
机器学习之心6 分钟前
一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
算法·lstm·transformer·北方苍鹰算法优化·多变量回归预测·ngo-transformer
yyt_cdeyyds17 分钟前
FIFO和LRU算法实现操作系统中主存管理
算法
daiyang123...39 分钟前
测试岗位应该学什么
数据结构
alphaTao43 分钟前
LeetCode 每日一题 2024/11/18-2024/11/24
算法·leetcode
kitesxian1 小时前
Leetcode448. 找到所有数组中消失的数字(HOT100)+Leetcode139. 单词拆分(HOT100)
数据结构·算法·leetcode
VertexGeek2 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust
石小石Orz2 小时前
Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~
javascript·人工智能·算法
jiao_mrswang2 小时前
leetcode-18-四数之和
算法·leetcode·职场和发展
qystca3 小时前
洛谷 B3637 最长上升子序列 C语言 记忆化搜索->‘正序‘dp
c语言·开发语言·算法
薯条不要番茄酱3 小时前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea