实验报告:实验4-树、二叉树与查找

集美大学课程实验报告-实验4:树、二叉树与查找

项目名称 内容
课程名称 数据结构
班级 网安2512
学号 202521336053
实验项目名称 树、二叉树与查找
上机实践日期 2026年5月12日
上机实践时间 2学时

一、目的

  • 掌握创建树的代码
  • 熟悉如何创建二叉排序树以及遍历二叉树的方法
  • 掌握如何查找二叉树

二、实验内容与设计思想

题目1:先序序列创建二叉树(编程题)

函数相关伪代码

算法:先序序列创建二叉树
输入:一段先序序列
输出:一个二叉排序树,和一个中序序列

1.输入一段先序序列
2.按照先序序列创建一个二叉排序树
3.依据二叉排序树输出一段中序序列
4.结束

函数代码

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

struct Node{
    char data;
    Node* lchild;
    Node* rchild;
    Node(char d){
        data=d;
        lchild=NULL;
        rchild=NULL;
    }
};
Node* buildTree(const string& s,int& index)
{
    if(index>=s.length())return NULL;
    char ch=s[index++];
    if(ch=='#')return NULL;
    Node* node=new Node(ch);
    node->lchild=buildTree(s,index);
    node->rchild=buildTree(s,index);
    return node;
}
void inorder(Node* root)
{
    if(root==NULL)return ;
    inorder(root->lchild);
    cout<<root->data<<" ";
    inorder(root->rchild);
}
void deleteTree(Node* root)
{
    if(root==NULL)return ;
    deleteTree(root->lchild);
    deleteTree(root->rchild);
    delete root;
}
int main()
{
    string s;
    while(cin>>s)
        {
            int index=0;
            Node* root=buildTree(s,index);
            inorder(root);
            cout<<endl;
            deleteTree(root);
        }
    return 0;
}

题目2:先序输出叶结点(函数题)

函数相关伪代码

算法:先序输出叶节点
输入:二叉排序树
输出:叶节点

1.输入一个二叉树的根节点
2.若为空树则输出NULL
3.若不为空树,先序找到没有左右孩子的结点
4.输出该结点的值并返回
5.结束

函数代码

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

题目3:求二叉树高度(函数题)

函数相关伪代码

算法:递归函数
输入:输入一个二叉树的根结点
输出:二叉树的高度

1.输入一个二叉树的根结点
2.若为空树,则输出0
3.若不为空,则先遍历左子树,遇到叶节点后返回,再遍历右子树
4.比较左子树和右子树的最大高度,取出最大值,即为二叉树的高度

函数代码

int GetHeight(BinTree BT)
{
    if(BT==NULL)return 0;
    int Lefthight=GetHeight(BT->Left);
    int Righthight=GetHeight(BT->Right);
    return (Lefthight>Righthight?Lefthight:Righthight)+1;
}

题目4:二叉树层次遍历(编程题)

函数相关伪代码

算法:循环输出
输入:二叉树的顺序存储的字符
输出:二叉树的层次遍历顺序的字符

1.输入一段二叉树的顺序排序的字符
2.开始遍历,遇到'#'不输出,表示空结点,遇到字母才输出,直到所有字母输出完整
3.结束

函数代码

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

int main()
{
    string s;
    cin>>s;
    int len=s.size();
    bool hasNode=false;
    for(int i=1;i<len;i++)
        {
            if(s[i]!='#')
            {
                hasNode=true;
                break;
            }
        }
    if(!hasNode)
    {
        cout<<"NULL"<<endl;
        return 0;
    }
    bool first=true;
    for(int i=1;i<len;i++)
        {
            if(s[i]!='#')
            {
                if(first)
                {
                    cout<<s[i];
                    first=false;
                }else
                {
                    cout<<" "<<s[i];
                }
            }
        }
    cout<<endl;
    return 0;
}

题目5、6:创建二叉树,并进行中序遍历,其中还有选择查找,插入,删除操作

函数相关伪代码

算法:二叉树的创建,遍历,插入,查找,删除
输入:一段数字
输出:完成二叉树的创建并中序遍历,后续可选择插入,查找和删除

1.输入一段数字
2.根据数字创建一个二叉排序树
3.进行中序遍历
4.接着可选择查找或者插入或者删除
5.结束

函数代码

#include<iostream>
using namespace std;

struct TreeNode {
	int data;
	TreeNode* left;
	TreeNode* right;
	TreeNode(int v):data(v),left(NULL),right(NULL){}
};

TreeNode* insert(TreeNode* root, int val)
{
	if (!root)return new TreeNode(val);
	if (val < root->data)root->left = insert(root->left, val);
	if (val > root->data)root->right = insert(root->right, val);
	return root;
}

void inorder(TreeNode* root)
{
	if (root == nullptr)return;
	inorder(root->left);
	cout << root->data << " ";
	inorder(root->right);
}

bool search(TreeNode* root, int val)
{
	if (!root)return false;
	if (val == root->data)return true;
	else if (val < root->data)
		return search(root->left, val);
	else
		return search(root->right, val);
}

TreeNode* findMin(TreeNode* root)
{
	while (root && root->left)
		root = root->left;
	return root;
}

TreeNode* deleteNode(TreeNode* root, int val)
{
	if (!root)return nullptr;
	if (val < root->data)
	{
		root->left = deleteNode(root->left, val);
	}
	else if (val > root->data)
	{
		root->right = deleteNode(root->right, val);
	}
	else
	{
		if (root->left == nullptr)
		{
			TreeNode* rightChild = root->right;
			delete root;
			return rightChild;
		}
		else if (root->right == nullptr)
		{
			TreeNode* leftChild = root->left;
			delete root;
			return leftChild;
		}
		TreeNode* minNode = findMin(root->right);
		root->data = minNode->data;
		root->right = deleteNode(root->right, minNode->data);
	}
	return root;
}

void deleteTree(TreeNode* root)
{
	if (!root)return;
	deleteTree(root->left);
	deleteTree(root->right);
	delete root;
}
int main()
{
	TreeNode* root = nullptr;
	int x;
	while (cin >> x )
	{
		root = insert(root, x);
	}
	cin.clear();               //清除failbit
	cin.ignore(1024, '\n');      //忽略剩余字符(包括 '#' 和换行)
	int choice, val;

	cout << "二叉搜索树操作演示\n";
	cout << "1. 插入\n2. 查找\n3. 删除\n4. 中序遍历\n5. 退出\n";

	while (true) {
		cout << "\n请选择操作: ";
		cin >> choice;
		switch (choice) {
		case 1:
			cout << "输入要插入的整数: ";
			cin >> val;
			root = insert(root, val);
			cout << "插入完成\n";
			break;
		case 2:
			cout << "输入要查找的整数: ";
			cin >> val;
			if (search(root, val))
				cout << "找到了!\n";
			else
				cout << "未找到。\n";
			break;
		case 3:
			cout << "输入要删除的整数: ";
			cin >> val;
			if (search(root, val)) {
				root = deleteNode(root, val);
				cout << "删除成功\n";
			}
			else {
				cout << "值不存在,无法删除\n";
			}
			break;
		case 4:
			cout << "中序遍历结果: ";
			inorder(root);
			cout << endl;
			break;
		case 5:
			deleteTree(root);
			cout << "程序退出\n";
			return 0;
		default:
			cout << "无效选项,请重新输入\n";
		}
	}
	return 0;
}

题目7:QQ账号查询

函数相关伪代码

算法:哈希表与平衡树的应用
输入:一段数字
输出:创建一个QQ账号并给予查找和删除等操作

1.初始化数据结构
2.输入一段数字,创建一个QQ号
3.后续可进行查找,删除该QQ账号
4.结束

函数代码

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

unordered_map<long long, string> hashMap;
map<long long, string> bstMap;

void insertAccount(long long qq, const string& name) {
    hashMap[qq] = name;
    bstMap[qq] = name;
    cout << "插入成功!\n";
}

void searchAccount(long long qq) {
    cout << "哈希表查找结果:";
    auto it = hashMap.find(qq);
    if (it != hashMap.end()) {
        cout << "找到,昵称:" << it->second << endl;
    }
    else {
        cout << "未找到该QQ号\n";
    }
    cout << "平衡树查找结果:";
    auto it2 = bstMap.find(qq);
    if (it2 != bstMap.end()) {
        cout << "找到,昵称:" << it2->second << endl;
    }
    else {
        cout << "未找到该QQ号\n";
    }
}

void deleteAccount(long long qq) {
    bool deleted = false;
    if (hashMap.erase(qq)) deleted = true;
    if (bstMap.erase(qq)) deleted = true;
    if (deleted) cout << "删除成功!\n";
    else cout << "账户不存在,删除失败\n";
}

void displayAll() {
    if (bstMap.empty()) {
        cout << "当前没有账户信息\n";
        return;
    }
    cout << "所有账号(按QQ号升序):\n";
    for (const auto& entry : bstMap) {
        cout << "QQ号:" << entry.first << ",昵称:" << entry.second << endl;
    }
}

int main() {
    int choice;
    long long qq;
    string name;
    cout << "=====QQ账户管理系统(演示哈希表与平衡树应用)=====\n";
    while (true) {
        cout << "\n请选择操作:\n";
        cout << "1.插入账户\n";
        cout << "2.查找账户\n";
        cout << "3.删除账户\n";
        cout << "4.显示所有账户(按QQ号排序)\n";
        cout << "5.退出\n";
        cout << "输入数字:";
        cin >> choice;
        switch (choice) {
        case 1:
            cout << "请输入QQ号(整数):";
            cin >> qq;
            cout << "请输入昵称:";
            cin >> name;
            insertAccount(qq, name);
            break;
        case 2:
            cout << "请输入要查找的QQ号:";
            cin >> qq;
            searchAccount(qq);
            break;
        case 3:
            cout << "请输入要删除的QQ号:";
            cin >> qq;
            deleteAccount(qq);
            break;
        case 4:
            displayAll();
            break;
        case 5:
            cout << "程序退出\n";
            return 0;
        default:
            cout << "无效输入,请重新选择\n";
            break;
        }
    }
}

三、实验使用环境

  • 操作系统:Windows11 专业版
  • 编程语言:C++
  • 开发工具:visual studio

四、实验步骤和调试过程

题目1:先序序列创建二叉树(编程题)

本机运行截图
1c4c38064193e1bf3e3ae1e6b9afb309

PTA提交截图
image

题目2:先序输出叶结点(函数题)

PTA提交截图
image

题目3:求二叉树高度(函数题)

PTA提交截图
image

题目4:二叉树层次遍历(编程题)

本机运行截图
892e2d04807f1b63d365453dcb8306ad

PTA提交截图
image

题目5,6:二叉树的创建,遍历,查找和删除

本机运行截图
d9db687a2c08fb02c333f937a70bfc3d

题目7:QQ账号查询

d1c2ef95ced7fb5cd2c052dae66a832a


五、实验小结

遇到的问题及解决方法:

1.问题:二叉树的删除操作的代码有点难

  • 解决方法:通过询问ai来分析该算法怎么执行并理解与应用
    2.问题:哈希表与平衡树的应用不太熟悉
  • 解决方法:通过看视频并询问ai来加以巩固

实验体会与收获:

  • 学会了二叉排序树的创建、查找和删除
  • 掌握了哈希表和平衡树的具体应用

六、附件

查询deepseek

posted @ 2026-05-13 17:35  望归时  阅读(5)  评论(0)    收藏  举报