实验4-树、二叉树与查找

一、目的

  • 掌握创建二叉树与树及二叉树上的基本操作
  • 熟练掌握熟练掌握树的递归结构及在其上的递归算法
  • 掌握二叉树的层次遍历
  • 掌握哈希表、平衡树的应用

二、实验内容与设计思想

  1. PTA编程:先序序列创建二叉树。
  2. PTA函数:先序输出叶结点。
  3. PTA函数:求二叉树高度。
  4. PTA编程:二叉树层次遍历(广度优先)
  5. 创建二叉排序树并遍历。给定一串50 30 80 20 40 90 10 25 35 85 23 88 #创建二叉排序树并对其进行中序遍历。
  6. 哈希表的应用:QQ账户查询。建议先伪代码再写代码。

题目1:先序序列创建二叉树

函数相关伪代码

先定义二叉树节点:data : 字符、 left : 二叉树节点指针、right: 二叉树节点指针
创建节点:node新节点,node.data = e、node.left = NULL、node.right = NULL
return node
中序: if root ≠ NULL: 中序遍历(root.left)
创建树:char ch; if (ch == '#'), root = NULL;
  else:root = makeNode(x); MakeTree(root->lchild);MakeTree(root->rchild);

函数代码

#include <iostream>
#include <string>
using namespace std;

typedef char ElemType;
typedef struct BiTNode {
    ElemType data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

BiTNode* makeNode(ElemType e) {
    BiTNode* node = new BiTNode;
    node->data = e;
    node->lchild = NULL;
    node->rchild = NULL;
    return node;
}

void InTraverse(BiTree root) {
    if (root != NULL) {
        InTraverse(root->lchild);
        cout << root->data << ' ';
        InTraverse(root->rchild);
    }
}

BiTree MakeTree(const string &str, int &index) {
    if (index >= (int)str.size()) return NULL;
    char x = str[index++];
    if (x == '#') {
        return NULL;
    } else {
        BiTNode* root = makeNode(x);
        root->lchild = MakeTree(str, index);
        root->rchild = MakeTree(str, index);
        return root;
    }
}

void DestroyTree(BiTree &root) {
    if (root != NULL) {
        DestroyTree(root->lchild);
        DestroyTree(root->rchild);
        delete root;
        root = NULL;
    }
}

int main() {
    string str;
    while (cin >> str) {
        int index = 0;
        BiTree root = MakeTree(str, index);
        InTraverse(root);
        cout << endl;
        DestroyTree(root);
    }
    return 0;
}

}

题目2:先序输出叶结点。

函数相关伪代码

先序遍历,if 是叶结点,输出空格和data。调用Leaf nodes are:输出空格+字符

函数代码

void PreorderPrintLeaves( BinTree BT ) {
    if (BT == NULL) return;
    if (BT->Left == NULL && BT->Right == NULL) {
        printf(" %c", BT->Data);
    }
    PreorderPrintLeaves(BT->Left);
    PreorderPrintLeaves(BT->Right);
}

题目3:求二叉树高度。

函数相关伪代码

if BT NULL:retrun 0
左高度 = GetHeight,右高度 = GetHeight
if 左高度 > 右高度:return 左高度 + 1
else:return 右高度 + 1

函数代码

int GetHeight( BinTree BT ) {
    if ( BT == NULL )
        return 0;
    int leftHeight = GetHeight( BT->Left );
    int rightHeight = GetHeight( BT->Right );
    if ( leftHeight > rightHeight )
        return leftHeight + 1;
    else
        return rightHeight + 1;
}

题目4:二叉树层次遍历(广度优先)

函数相关伪代码

 cin s ;if  s.size ≤ 1/ s[1] == '#': return NULL
 first ← true                       
int i=1;i<s.size ;++i;       
if  s[i] ≠ '#':  if first = false: 输出 s[i]  first ← false

函数代码

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    cin >> s;
    if (s.size() <= 1 || s[1] == '#') {
        cout << "NULL" << endl;
        return 0;
    }

    bool first = true;
    for (int i = 1; i < s.size(); ++i) {
        if (s[i] != '#') {
            if (!first) cout << ' ';
            cout << s[i];
            first = false;
        }
    }
    cout << endl;
    return 0;
}

题目5:创建二叉排序树并遍历。给定一串50 30 80 20 40 90 10 25 35 85 23 88 #创建二叉排序树并对其进行中序遍历。

函数相关伪代码

结点:data lchild rchild
创建新结点:node.data = e node.lchild = NULL node.rchild = NULL
插入:if root=NULL root=e
else if e < root.data   (root.lchild, e)
else if e > root.data   (root.rchild, e)
构造树root = NULL
cin x if x 不= '#' 插入(root, val)
中序遍历:if root != NULL   中序遍历(root.lchild)  输出 root.data  中序遍历(root.rchild)

函数代码

#include <iostream>
#include <string>
using namespace std;

typedef int ElemType;               
typedef struct BiTNode {
    ElemType data;
    struct BiTNode* lchild, * rchild;
} BiTNode, * BiTree;

BiTNode* makeNode(ElemType e)
{
    BiTNode* node = new BiTNode;
    node->data = e;
    node->lchild = NULL;
    node->rchild = NULL;
    return node;
}

void InsertBST(BiTree& root, ElemType e)
{
    if (root == NULL) {
        root = makeNode(e);
        return;
    }
    if (e < root->data)
        InsertBST(root->lchild, e);
    else if (e > root->data)
        InsertBST(root->rchild, e);
}

void PreTraverse(BiTree root)
{
    if (root != NULL)
    {
        cout << root->data << " "; 
        PreTraverse(root->lchild);
        PreTraverse(root->rchild);
    }
}

void InTraverse(BiTree root)
{
    if (root != NULL)
    {
        InTraverse(root->lchild);
        cout << root->data << " ";  
        InTraverse(root->rchild);
    }
}

void PostTraverse(BiTree root)
{
    if (root != NULL)
    {
        PostTraverse(root->lchild);
        PostTraverse(root->rchild);
        cout << root->data << " ";
    }
}

void MakeTree(BiTree& root)
{
    root = NULL;       
    string token;
    while (cin >> token) {
        if (token == "#") break;    
        ElemType val = stoi(token);  
        InsertBST(root, val);
    }
}

int main()
{
    BiTree root;
    MakeTree(root);
    InTraverse(root);
    cout << endl;   
    return 0;
}

题目6:哈希表的应用:QQ账户查询

函数相关伪代码

创建哈希表: 键为字符串(QQ号) 值为字符串(昵称)
查找:在哈希表中查找键 if 找到:return "值" 
 else:return "未找到 键"
添加账户:if 哈希表中不存在键  键 ← "David"return"已添加"
else: return " 已存在!"
删除账户:在哈希表中删除键,输出 "删除后,   是否存在? "
  if 表中仍存在 return "是"
else:return "否"
输出:QQ:“” 昵称:“”

函数代码

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

int main() {
    unordered_map<string, string> qqBook;

    qqBook["1234567890"] = "Alice";
    qqBook["9876543210"] = "Bob";
    qqBook["5555555555"] = "Charlie";

    string qq = "1234567890";
    if (qqBook.find(qq) != qqBook.end()) {
        cout << "QQ " << qq << " 的昵称是:" << qqBook[qq] << endl;
    }
    else {
        cout << "未找到 QQ " << qq << endl;
    }

    string newQQ = "1111111111";
    if (qqBook.count(newQQ) == 0) {  
        qqBook[newQQ] = "David";
        cout << "已添加 QQ " << newQQ << endl;
    }
    else {
        cout << "QQ " << newQQ << " 已存在!" << endl;
    }

    qqBook.erase("5555555555");   
    cout << "删除后,5555555555 是否存在? "
        << (qqBook.count("5555555555") ? "是" : "否") << endl;

    cout << "\n当前所有账户:" << endl;
    for (const auto& p : qqBook) {
        cout << "QQ: " << p.first << "  昵称: " << p.second << endl;
    }
    return 0;
}

三、实验使用环境

  • 操作系统:Windows 11
  • 编程语言:C++
  • 开发工具:Visual Studio 2026

四、实验步骤和调试过程

题目1:先序序列创建二叉树

b984d89f45e9863023fe4f4a349e3729

题目2:先序输出叶结点。

image

题目3:求二叉树高度。

image

题目4:二叉树层次遍历(广度优先)

image

题目5:创建二叉排序树并遍历。给定一串50 30 80 20 40 90 10 25 35 85 23 88 #创建二叉排序树并对其进行中序遍历。

5bffb164c7772d27ffda6d0d446de4f8912a7dbd166968b47eb1e561468c8ca5a382e3bf2b5cfcb148fa51125fdbef245e76bd952b4c485079f0e9f1a8dcc317

题目6:哈希表的应用:QQ账户查询

99cba33fab60f7ea6136b8d400d00382
26023264a6e989c93f14340ff4388708

五、实验小结

遇到的问题及解决方法:

  1. 问题:程序崩溃找不到原因,
  • 解决方法:问了豆包

实验体会和收获:

  1. 体会:二叉树在生活中应用很广泛
  2. 收获:1.学会了创建二叉树和二叉排序树 2.学会了先、中、后序遍历 3.学会用BST查找

六、附件

-无

posted @ 2026-05-10 17:32  lansariel  阅读(12)  评论(0)    收藏  举报