数据结构实训——查找

声明:  以下是我们学校在学习数据结构时进行的实训,如涉及侵权马上删除文章

声明:本文主要用作技术分享,所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险,并遵循相关法律法规。

一、实训类型

   验证性实训

二、实训目的与任务

1.掌握顺序查找、折半查找算法的基本思想;

2. 掌握顺序查找、折半查找算法的实现方法;

3. 验证顺序查找、折半查找算法的时间性能。

4. 掌握二叉排序树定义和特性;

5. 掌握二叉排序树的建立方法,并实现基于二叉排序树的查找技术。

6. 掌握散列查找的基本思想;

7. 掌握闭散列表的构造方法;

8. 掌握散列技术的查找性能。

三、实训基本原理

1.顺序查找

顺序查找又称线性查找,是最基本的查找技术之一。

其基本思想为:从线性表的一端向另一端逐个将关键码与给定值进行比较,若相等,则查找成功,给出该记录在表中的位置;若整个表检测完仍未找到与给定值相等的关键码,则查找失败,给出失败信息。

顺序查找在每次比较后都要判断查找是否越界,降低了查找速度。

将顺序查找算法改进:设置“哨兵”。哨兵就是待查值,将它放在查找方向的“尽头”处,免去了在查找过程中每一次比较后都要判断查找位置是否越界,从而提高查找速度。

2.折半查找

折半查找技术的使用前提:

·线性表中的记录必须按关键码有序;

·线性表必须采用顺序存储。

折半查找的基本思想为:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键码相等,则查找成功;若给定值小于中间记录的关键码,则在中间记录的左半区继续查找;若给定值大于中间记录的关键码,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所查找的区域无记录,查找失败。

3.二叉排序树

是一种可以较快速地使得记录的插入、删除与查找操作很快地完成一种存储数据的方法。

二叉排序树(Binary Sort Tree)又称二叉查找树,它或者是一棵空的二叉树,或者是具有下列性质的二叉树:

⑴ 若它的左子树不空,则左子树上所有结点的值均小于根结点的值;

⑵ 若它的右子树不空,则右子树上所有结点的值均大于或等于根结点的值;

⑶ 它的左右子树也都是二叉排序树。

4.散列表的查找技术

散列技术是在记录的存储位置和它的关键码之间建立一个确定的对应关系H,使得每个关键码key和唯一的一个存储位置H(key)相对应。在查找时,根据这个确定的对应关系找到给定值k的映射H(k),若查找集合中存在这个记录,则必定在H(k)的位置上。采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表(Hash Table),将关键码映射为散列表中适当存储位置的函数称为散列函数(Hash Function),所得的存储位置址称为散列地址。

散列既是一种存储方法,也是一种查找方法。但是散列不是一种完整的存储结构,因为它只是通过记录的关键码定位该记录,很难完整地表达记录之间的逻辑关系,所以,散列主要是面向查找的存储结构。

一般来说,散列技术的查找速度要比前面介绍的基于关键码比较的查找技术的查找速度高。但是,散列方法一般不适用于允许多个记录有同样关键码的情况。

四、实训设备

1.计算机

五、实训内容

1. 输入10个不同的实型数据,利用顺序查找方法完成给定值的查找。

2. 输入10个有序整型数据,利用折半查找方法完成给定值的查找。

3. 输入10个整型数据,构造一棵二叉排序树,并执行数据删除与数据插入操作。

4. 输入10个整型数据,构造一棵二叉排序树,完成该二叉树的前序、中序、后序遍历,并分析遍历结果。(设计实训选做)

5. 针对自己的班集体中的“学生姓名”设计一个哈希表,使得平均查找长度不超过2,完成相应的建表和查表程序。基本要求:假设人名为中国姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构照,用链表法处理冲突。

1. 输入10个不同的实型数据,利用顺序查找方法完成给定值的查找。

#include <stdio.h>

#define M  100          /*顺序表的表长*/

typedef int KeyType;           /*关键字类型为int型*/

typedef struct

{   KeyType key; /*存放关键字,KeyType为关键字类型*/

}SearchL;

int SeqSearch(SearchL  r[],int n,KeyType k)

{  /*顺序查找算法函数,表中元素下标为1到n*/  

    int i=n;  

    r[0].key=k; /*设元素r[o]为要查找的关键字k(即监视哨)*/  

    while (r[i].key!=k)  /*从后向前顺序比较*/     

         i--;  

    return(i); /*返回查找元素下标,当为0时表示查找失败*/

}

int main()

{

    SearchL A[M];

    int i,n,m,k;

    printf("请输入查找表的长度\n");

    scanf("%d",&n);

    printf("请输入查找表的数据\n");

    for(i=1;i<=n;i++)

      scanf("%d",&A[i].key);

      printf("请输入待查的数据\n");

        scanf("%d",&k);

       m=SeqSearch(A,n,k);

    if(m==0)

    printf("表中没有此数据");

    else

    printf("表中此数据在%d位置\n",m);

    return 0;

}

2. 输入10个有序整型数据,利用折半查找方法完成给定值的查找。

#include <stdio.h>

#define M  100          /*顺序表的表长*/

typedef int KeyType;           /*关键字类型为int型*/

typedef struct

{   KeyType key; /*存放关键字,KeyType为关键字类型*/

}SearchL;

int BinarySearch(SearchL  r[], int n, KeyType k)

    int low = 1, high = n, mid;

    while (low <= high)

    {

        mid = (low + high) / 2;

        if (r[mid].key == k)

            return mid;

        else if (r[mid].key < k)

            low = mid + 1;

        else

            high = mid - 1;

    }

    return 0;  // 未找到返回 0

}

int main()

{

    SearchL A[M];

    int i,n,m,k;

    printf("请输入查找表的长度\n");

    scanf("%d",&n);

    printf("请输入查找表的数据\n");

    for(i=1;i<=n;i++)

        scanf("%d",&A[i].key);

    printf("请输入待查的数据\n");

    scanf("%d",&k);

    m = BinarySearch(A,n,k);

    if(m==0)

        printf("表中没有此数据");

    else

        printf("表中此数据在%d位置\n",m);

    return 0;

}

3. 输入10个整型数据,构造一棵二叉排序树,并执行数据删除与数据插入操作。

#include <stdio.h>

#include <stdlib.h>

// 二叉树节点结构体

typedef struct TreeNode {

    int data;

    struct TreeNode *left;

    struct TreeNode *right;

} TreeNode;

// 创建新节点

TreeNode* createNode(int data) {

    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));

    newNode->data = data;

    newNode->left = NULL;

    newNode->right = NULL;

    return newNode;

}

// 插入节点

TreeNode* insert(TreeNode* root, int data) {

    if (root == NULL) {

        return createNode(data);

    }

    if (data < root->data) {

        root->left = insert(root->left, data);

    } else if (data > root->data) {

        root->right = insert(root->right, data);

    }

    return root;

}

// 中序遍历

void inorderTraversal(TreeNode* root) {

    if (root!= NULL) {

        inorderTraversal(root->left);

        printf("%d ", root->data);

        inorderTraversal(root->right);

    }

}

// 查找最小节点

TreeNode* findMin(TreeNode* root) {

    while (root->left!= NULL) {

        root = root->left;

    }

    return root;

}

// 删除节点

TreeNode* deleteNode(TreeNode* root, int data) {

    if (root == NULL) {

        return root;

    }

    if (data < root->data) {

        root->left = deleteNode(root->left, data);

    } else if (data > root->data) {

        root->right = deleteNode(root->right, data);

    } else {

        if (root->left == NULL) {

            TreeNode* temp = root->right;

            free(root);

            return temp;

        } else if (root->right == NULL) {

            TreeNode* temp = root->left;

            free(root);

            return temp;

        }

        TreeNode* temp = findMin(root->right);

        root->data = temp->data;

        root->right = deleteNode(root->right, temp->data);

    }

    return root;

}

int main() {

    TreeNode* root = NULL;

    int data;

    printf("输入 10 个整型数据:\n");

    for (int i = 0; i < 10; i++) {

        scanf("%d", &data);

        root = insert(root, data);

    }

    printf("初始二叉排序树的中序遍历结果:\n");

    inorderTraversal(root);

    int delData, insData;

    printf("\n输入要删除的数据:");

    scanf("%d", &delData);

    root = deleteNode(root, delData);

    printf("删除后二叉排序树的中序遍历结果:\n");

    inorderTraversal(root);

    printf("\n输入要插入的数据:");

    scanf("%d", &insData);

    root = insert(root, insData);

    printf("插入后二叉排序树的中序遍历结果:\n");

    inorderTraversal(root);

    return 0;

}

4. 输入10个整型数据,构造一棵二叉排序树,完成该二叉树的前序、中序、后序遍历,并分析遍历结果。(设计实训选做)

#include <stdio.h>

#include <stdlib.h>

// 二叉树节点结构体

typedef struct TreeNode {

    int data;

    struct TreeNode *left;

    struct TreeNode *right;

} TreeNode;

// 创建新节点

TreeNode* createNode(int data) {

    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));

    newNode->data = data;

    newNode->left = NULL;

    newNode->right = NULL;

    return newNode;

}

// 插入节点

TreeNode* insert(TreeNode* root, int data) {

    if (root == NULL) {

        return createNode(data);

    }

    if (data < root->data) {

        root->left = insert(root->left, data);

    } else if (data > root->data) {

        root->right = insert(root->right, data);

    }

    return root;

}

// 前序遍历

void preorderTraversal(TreeNode* root) {

    if (root!= NULL) {

        printf("%d ", root->data);

        preorderTraversal(root->left);

        preorderTraversal(root->right);

    }

}

// 中序遍历

void inorderTraversal(TreeNode* root) {

    if (root!= NULL) {

        inorderTraversal(root->left);

        printf("%d ", root->data);

        inorderTraversal(root->right);

    }

}

// 后序遍历

void postorderTraversal(TreeNode* root) {

    if (root!= NULL) {

        postorderTraversal(root->left);

        postorderTraversal(root->right);

        printf("%d ", root->data);

    }

}

int main() {

    TreeNode* root = NULL;

    int data;

    printf("输入 10 个整型数据:\n");

    for (int i = 0; i < 10; i++) {

        scanf("%d", &data);

        root = insert(root, data);

    }

    printf("前序遍历结果:\n");

    preorderTraversal(root);

    printf("\n");

    printf("中序遍历结果:\n");

    inorderTraversal(root);

    printf("\n");

    printf("后序遍历结果:\n");

    postorderTraversal(root);

    printf("\n");

    // 分析遍历结果

    printf("分析:\n");

    printf("前序遍历首先访问根节点,然后递归遍历左子树和右子树,输出顺序反映了构建树的顺序。\n");

    printf("中序遍历先递归遍历左子树,然后访问根节点,再递归遍历右子树,输出结果是有序的(对于二叉排序树)。\n");

    printf("后序遍历先递归遍历左子树和右子树,最后访问根节点,常用于释放二叉树的内存等操作。\n");

    return 0;

}

六、实训注意事项

1.题目自选,至少要完成三个题目。

2.若完成题目个数多或设计的算法效率高,予以加分。

七、预习与思考题

1.各种查找方法比较

八、实训报告要求

1.书写算法或完整程序。

2.若调试程序时程序出错,请分析出错原因及修改方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/483556.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

指针(上)

目录 内存和地址 指针变量和地址 取地址&#xff08;&&#xff09; 解引用&#xff08;*&#xff09; 大小 类型 意义 const修饰 修饰变量 修饰指针 指针运算 指针- 整数 指针-指针 指针的关系运算 野指针 概念 成因 避免 assert断言 指针的使用 strl…

13TB的StarRocks大数据库迁移过程

公司有一套StarRocks的大数据库在大股东的腾讯云环境中&#xff0c;通过腾讯云的对等连接打通&#xff0c;通过dolphinscheduler调度datax离线抽取数据和SQL计算汇总&#xff0c;还有在大股东的特有的Flink集群环境&#xff0c;该环境开发了flink开发程序包部署&#xff0c;实时…

ARP表、MAC表、路由表的区别和各自作用

文章目录 ARP表、MAC表、路由表的区别和各自作用同一网络内:ARP表request - 请求reply - 响应 MAC地址在同一网络内,交换机如何工作? 不同网络路由表不同网络通信流程PC1到路由器路由器到PC2流程图 简短总结 ARP表、MAC表、路由表的区别和各自作用 拓扑图如下: 同一网络内:…

第七课 Unity编辑器创建的资源优化_UI篇(UGUI)

上期我们学习了简单的Scene优化&#xff0c;接下来我们继续编辑器创建资源的UGUI优化 UI篇&#xff08;UGUI&#xff09; 优化UGUI应从哪些方面入手&#xff1f; 可以从CPU和GPU两方面考虑&#xff0c;CPU方面&#xff0c;避免触发或减少Canvas的Rebuild和Rebatch&#xff0c…

微服务搭建----springboot接入Nacos2.x

springboot接入Nacos2.x nacos之前用的版本是1.0的&#xff0c;现在重新搭建一个2.0版本的&#xff0c;学如逆水行舟&#xff0c;不进则退&#xff0c;废话不多说&#xff0c;开搞 1、 nacos2.x搭建 1&#xff0c;首先第一步查询下项目之间的版本对照&#xff0c;不然后期会…

Node.js 实战: 爬取百度新闻并序列化 - 完整教程

很多时候我们需要爬取一些公开的网页内容来做一些数据分析和统计。而多数时候&#xff0c;大家会用到python &#xff0c;因为实现起来很方便。但是其实Node.js 用来爬取网络内容&#xff0c;也是非常强大的。 今天我向大家介绍一下我自己写的一个百度新闻的爬虫&#xff0c;可…

Flink四大基石之State(状态) 的使用详解

目录 一、有状态计算与无状态计算 &#xff08;一&#xff09;概念差异 &#xff08;二&#xff09;应用场景 二、有状态计算中的状态分类 &#xff08;一&#xff09;托管状态&#xff08;Managed State&#xff09;与原生状态&#xff08;Raw State&#xff09; 两者的…

底部导航栏新增功能按键

场景需求&#xff1a; 在底部导航栏添加power案件&#xff0c;单击息屏&#xff0c;长按 关机 如下实现图 借此需求&#xff0c;需要掌握技能&#xff1a; 底部导航栏如何实现新增、修改、删除底部导航栏流程对底部导航栏部分样式如何修改。 比如放不下、顺序排列、坑点如…

如何在 Firefox 中清除特定网站的浏览历史记录

以下&#xff0c;我将介绍如何清除特定网站的浏览历史记录。清除历史记录可以保护隐私&#xff0c;特别是在公共或共享设备上使用时&#xff0c;还能节省设备存储空间&#xff0c;避免浏览历史占用过多内存。 如何清除特定网站的浏览历史记录 在 Firefox 中&#xff0c;清除特…

SpringMVC(二)

Model 以Map方式进行存储&#xff0c;用于向作用域中存值。 注意&#xff1a;在Model中增加模型数据&#xff0c;若不指定key&#xff0c;则默认使用对象的类型作为key Controller //控制器类 public class IndexController {RequestMapping("/index3")public Strin…

ABE 中的隐藏属性:DIPPE(去中心化内积谓词加密)

1. 引言 相关论文有&#xff1a; Yan Michalevsky 和 Marc Joye 2018年论文 Decentralized policy-hiding ABE with receiver privacy&#xff0c;发表于23rd European Symposium on Research in Computer Security, ESORICS 2018。Amit Sahai 和 Brent Waters 2005年论文 Fu…

计算机网络——不同版本的 HTTP 协议

介绍 HTTP&#xff0c;即超文本传输协议&#xff08;HyperText Transfer Protocol&#xff09;&#xff0c;是应用层的一个简单的请求-响应协议&#xff0c;它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。本文将介绍 HTTP 协议各个版本。 HTTP/1.0 HTTP/1…

Linux——基础命令(2) 文件内容操作

目录 ​编辑 文件内容操作 1.Vim &#xff08;1&#xff09;移动光标 &#xff08;2&#xff09;复制 &#xff08;3&#xff09;剪切 &#xff08;4&#xff09;删除 &#xff08;5&#xff09;粘贴 &#xff08;6&#xff09;替换,撤销,查找 &#xff08;7&#xff…

嵌入式硬件实战提升篇(三)商用量产电源设计方案 三路电源输入设计 电源管理 多输入供电自动管理 DCDC降压

引言&#xff1a;本文你能实际的了解到实战量产产品中电源架构设计的要求和过程&#xff0c;并且从实际实践出发搞懂电源架构系统&#xff0c;你也可以模仿此架构抄板到你自己的项目&#xff0c;并结合硬件篇之前的项目以及理论形成正真的三路电源输入设计与开发板电源架构块供…

30分钟学会正则表达式

正则表达式是对字符串操作的一种逻辑公式&#xff0c;就是用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个“规则字符串”&#xff0c;这个“规则字符串”用来表达对字符串的一种过滤逻辑。 作用 匹配 查看一个字符串是否符合正则表达式的语法 搜索 正…

如何手搓一个智能激光逗猫棒

背景 最近家里的猫胖了&#xff0c;所以我就想做个逗猫棒。找了一圈市场上的智能逗猫棒&#xff0c;运行轨迹比较单一&#xff0c;互动性不足。 轨迹单一&#xff0c;活动范围有限 而我希望后续可以结合人工智能物联网&#xff0c;通过摄像头来捕捉猫的位置&#xff0c;让小…

【C语言】递归的内存占用过程

递归 递归是函数调用自身的一种编程技术。在C语言中&#xff0c;递归的实现会占用内存栈&#xff08;Call Stack&#xff09;&#xff0c;每次递归调用都会在栈上分配一个新的 “栈帧&#xff08;Stack Frame&#xff09;”&#xff0c;用于存储本次调用的函数局部变量、返回地…

Bert+CRF的NER实战

CRF&#xff08;条件随机场-Conditional Random Field&#xff09; 原始本文&#xff1a;我在北京吃炸酱面 标注示例&#xff08;采用BIO标注方式&#xff09;&#xff1a; 我O在O北B-PLA京I-PLA吃O炸B-FOOD酱I-FOOD面I-FOOD CRF&#xff1a; 目的&#xff1a;提出一些不可能…

pycharm链接neo4j数据库(简单)

1.安装pycharm 2.安装库 pip install py2neo -i https://pypi.tuna.tsinghua.edu.cn/simple 3.代码试运行 from py2neo import Graph, Node, Relationship# 连接到Neo4j数据库&#xff0c;使用Bolt协议 graph Graph("bolt://localhost:7687", auth("neo…

故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab) 源码设计 %% 初始化 clear close all clc disp(此程序务必用2023b及其以上版本的MATLAB!否则会报错!) warning off %