数据结构实验六

news/2025/1/10 16:50:26/文章来源:https://www.cnblogs.com/-Xuxu/p/18664254

石 家 庄 铁 道 大 学
实 验 报 告

课程名称: 数据结构与算法设计 任课教师: 刘 丹 实验日期:2024.12.15
班 级: 信2305-3 姓 名: 徐戌 学 号: 20234316

实验项目名称:实验六
一、 实验目的
1.掌握插入排序的方法及效率分析
2.掌握选择排序的方法及效率分析
3.掌握交换排序的方法及效率分析
4.掌握归并排序的方法及效率分析
二、 实验内容

三、 设计文档

四、 源程序
6-4 快速排序

include<stdio.h>

include<stdlib.h>

typedef int KeyType;
typedef struct
{
KeyType elem; /elem[0]一般作哨兵或缓冲区/
int Length;
}SqList;
void CreatSqList(SqList L);/待排序列建立,由裁判实现,细节不表
/
int Partition ( SqList L,int low, int high );
void Qsort ( SqList L,int low, int high );
int main()
{
SqList L;
int i;
CreatSqList(&L);
Qsort(L,1,L.Length);
for(i=1;i<=L.Length;i++)
printf("%d ",L.elem[i]);
return 0;
}
void Qsort ( SqList L,int low, int high )
{
int pivotloc;
if(low<high)
{
pivotloc = Partition(L, low, high ) ;
Qsort (L, low, pivotloc-1) ;
Qsort (L, pivotloc+1, high );
}
}
int Partition(SqList L, int low, int high) {
// 选择第一个元素作为基准值
KeyType pivot = L.elem[low];
while (low < high) {
// 从右往左找第一个小于基准值的元素
while (low < high && L.elem[high] >= pivot) {
high--;
}
// 将找到的元素放到左边合适位置(也就是low指向的位置)
L.elem[low] = L.elem[high];
// 从左往右找第一个大于基准值的元素
while (low < high && L.elem[low] <= pivot) {
low++;
}
// 将找到的元素放到右边合适位置(也就是high指向的位置)
L.elem[high] = L.elem[low];
}
// 把基准值放到最终正确的位置(也就是low和high相遇的位置)
L.elem[low] = pivot;
return low;
}
6-5 堆排序

include<stdio.h>

include<stdlib.h>

typedef int KeyType;
typedef struct {
KeyType elem; /elem[0]一般作哨兵或缓冲区/
int Length;
}SqList;
typedef SqList HeapType;
void CreatSqListHeapType L);/待排序列建立,由裁判实现,细节不表
/
void HeapAdjust( HeapType H, int s, int m);
void HeapSort( HeapType H);
int main()
{
HeapType L;
int i;
CreatSqList(&L);
HeapSort(L);
for(i=1;i<=L.Length;i++)
{
printf("%d ",L.elem[i]);
}
return 0;
}
void HeapSort( HeapType H)
{ /堆顺序表H进行堆排序/
int i; KeyType rc;
/建立初始堆/
for( i=H.Length/2;i>0; i--)
{
HeapAdjust(H, i, H.Length);
}
for(i=H.Length;i>1;i--)
{
rc=H.elem[1];
H.elem[1]=H.elem[i];
H.elem[i]=rc;
HeapAdjust(H, 1, i-1);
}
}
void HeapAdjust(HeapType H, int s, int m) {
// 取出当前要调整的节点的值
KeyType temp = H.elem[s];
// 从当前节点的左孩子节点开始(数组下标表示,左孩子为2 * s)
for (int j = 2 * s; j <= m; j *= 2) {
// 如果有右孩子(下标为2 * s + 1)且右孩子比左孩子大,则选择右孩子
if (j < m && H.elem[j] < H.elem[j + 1]) {
j++;
}
// 如果当前节点已经大于等于子节点中的较大者,就不用调整了,直接break
if (temp >= H.elem[j]) {
break;
}
// 将较大的子节点值上移到当前节点位置
H.elem[s] = H.elem[j];
// 更新当前节点的下标,继续向下调整
s = j;
}
// 将之前取出的当前节点的值放到合适的位置
H.elem[s] = temp;
}
6-6 归并排序

include<stdio.h>

include<stdlib.h>

typedef int KeyType;
typedef struct {
KeyType elem; /elem[0]一般作哨兵或缓冲区/
int Length;
}SqList;
void CreatSqList(SqList L);/待排序列建立,由裁判实现,细节不表
/
void MergeSort(SqList L,int low,int high);
void Merge(SqList L,int low,int m,int high);
int main()
{
SqList L;
int i;
CreatSqList(&L);
MergeSort(L,1,L.Length);
for(i=1;i<=L.Length;i++)
{
printf("%d ",L.elem[i]);
}
return 0;
}
void MergeSort(SqList L,int low,int high)
{
/用分治法进行二路归并排序/
int mid;
if(low<high) /区间长度大于1/
{
mid=(low+high)/2; /分解/
MergeSort(L,low,mid); /递归地对low到mid序列排序 /
MergeSort(L,mid+1,high); /
递归地对mid+1到high序列排序 /
Merge(L,low,mid,high); /
归并
/
}
}
// 归并操作函数
void Merge(SqList L, int low, int m, int high) {
// 计算两个子序列的长度
int n1 = m - low + 1;
int n2 = high - m;

// 创建两个临时数组来存储两个子序列
KeyType left[n1];
KeyType right[n2];// 将原数组中的两个子序列分别复制到临时数组中
for (int i = 0; i < n1; i++) {left[i] = L.elem[low + i];
}
for (int j = 0; j < n2; j++) {right[j] = L.elem[m + 1 + j];
}// 初始化索引,分别用于遍历两个临时数组以及原数组归并后的位置
int i = 0, j = 0, k = low;
// 比较两个临时数组中的元素,将较小的放入原数组相应位置
while (i < n1 && j < n2) {if (left[i] <= right[j]) {L.elem[k++] = left[i++];} else {L.elem[k++] = right[j++];}
}// 将left数组中剩余的元素复制到原数组(如果有)
while (i < n1) {L.elem[k++] = left[i++];
}// 将right数组中剩余的元素复制到原数组(如果有)
while (j < n2) {L.elem[k++] = right[j++];
}

}
6-7 直接插入排序

include<stdio.h>

include<stdlib.h>

typedef int KeyType;
typedef struct {
KeyType elem; /elem[0]一般作哨兵或缓冲区/
int Length;
}SqList;
void CreatSqList(SqList L);/待排序列建立,由裁判实现,细节不表
/
void InsertSort(SqList L);
int main()
{
SqList L;
int i;
CreatSqList(&L);
InsertSort(L);
for(i=1;i<=L.Length;i++)
{
printf("%d ",L.elem[i]);
}
return 0;
}
void InsertSort(SqList L) {
for (int i = 2; i <= L.Length; i++) { // 从第二个元素开始,将其插入前面已排好序的序列中
KeyType temp = L.elem[i]; // 取出当前要插入的元素
int j = i - 1;
// 在已排序的序列中查找合适的插入位置
while (j >= 1 && L.elem[j] > temp) {
L.elem[j + 1] = L.elem[j]; // 向后移动元素,腾出插入位置
j--;
}
L.elem[j + 1] = temp; // 将元素插入合适的位置
}
}
6-8 希尔排序的实现

include<stdio.h>

include<stdlib.h>

typedef int KeyType;
typedef struct {
KeyType elem; /elem[0]一般作哨兵或缓冲区/
int Length;
}SqList;
void CreatSqList(SqList L);/待排序列建立,由裁判实现,细节不表
/
void ShellInsert(SqList L,int dk);
void ShellSort(SqList L);

int main()
{
SqList L;
int i;
CreatSqList(&L);
ShellSort(L);
for(i=1;i<=L.Length;i++)
{
printf("%d ",L.elem[i]);
}
return 0;
}
void ShellSort(SqList L)
{
/按增量序列dlta[0…t-1]对顺序表L作Shell排序,假设规定增量序列为5,3,1/
int k;
int dlta[3]={5,3,1};
int t=3;
for(k=0;k<t;++k)
ShellInsert(L,dlta[k]);
}
void ShellInsert(SqList L, int dk) {
for (int i = dk + 1; i <= L.Length; i++) {
KeyType temp = L.elem[i];
int j = i - dk;
while (j > 0 && L.elem[j] > temp) {
L.elem[j + dk] = L.elem[j];
j -= dk;
}
L.elem[j + dk] = temp;
}
}
五、 个人体会
在数据结构实验排序过程中,遇到诸多问题。首先,代码实现冒泡排序时,内层循环条件出错,导致排序结果混乱,经过仔细对比算法逻辑,纠正循环边界得以解决。其次,对于快速排序的递归部分理解困难,函数调用栈频频溢出,通过绘制递归展开图深入剖析,优化了递归终止条件。还有,使用系统自带排序函数与自定义排序对比测试时,数据类型不匹配引发报错,仔细检查数据类型转换后正常运行。
实验感想:这次实验让我深知理论与实践差距,编码中一个小疏忽就全盘皆错。但攻克难题后,对排序算法理解通透许多,编程能力、调试技巧都显著提升,也更有信心面对后续复杂的数据结构挑战。

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

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

相关文章

通过本地私有的镜像仓库harbor解决网络原因导致的jdk无法加载而造成的docker打包错误.v2.250110

​各种网络原因,或是docker.io无法访问,或是阿里的镜像源故障,导致java打包发布的时候报错,很影响代码发布的质量。解决思路:墙出去把jdk下载下来,代码使用本地的harbor库进行引用,一劳永逸。此解决方法也适用于国外优质不频繁变动的镜像源的本地化使用。解决方法 1. 自…

[题目记录]AGC005E Sugigma: The Showdown

一道通过自己生成思路做出的思维题 . 通过分析博弈过程发现问题其实没有那么复杂 , 然后层层分析转化问题即可 .AGC005E Sugigma: The Showdown 题意 给出两棵树 , 点的编号相同 , 连边方式不同 . 初始 A 在树 \(a\) 上的点 \(x\) , B 在树 \(b\) 上的点 \(y\) , 两人轮流走 , …

代码随想论算法训练营第3天 | 链表理论基础,203.移除链表元素,707.设计链表,206.反转链表

一、刷题部分 1.1 链表理论基础原文链接:代码随想录 题目链接:🈚️链表是由一个个节点串联而成的,节点包含数据域和指针域,数据域用来存放数据,而指针域实现了节点之间的串联。 链表中有单链表、双链表、循环链表:链表的物理空间是不连续的,通过指针存储下一节点的物理…

ABAP配置:OY01 定义国家/地区

配置:OY01 定义国家/地区 事务代码:OY01 配置路径 SPRO-ABAP平台-常规设置-设置国家-定义国家/地区 配置路径截图配置描述 国家是SAP里面一个非常重要的概念,SAP国家概念涉及公司代码、工厂、主数据、跨国银行交易,系统默认自带ISO相关的国家编码,在S/4中,一些配置转移到…

关于GTM,这些评价指标你都知道吗?

目标跟踪指标是企业实现持续增长和盈利的重要工具。通过定期监控和分析这些指标,企业可以及时发现潜在问题并采取相应的改进措施,以保持其竞争力并实现业务目标。因此,企业应该重视这些指标的应用,并不断优化其监控和分析流程,以确保其业务运营的顺利进行。Goal Tracking …

ODX诊断数据库转换工具 - DDC

INTEWORK-DDC (Diagnostic Database Convertor) 是将诊断调查问卷转换为标准ODX(2.2.0)数据库的工具。ODX是格式标准化的诊断数据库文件,我们在诊断不同的车或者不同的ECU时,只需要加载适配这个车型或ECU的ODX文件即可,而无需对诊断仪做任何改变。ODX统一了诊断文件的格式,…

异地多活架构进阶:如何解决写后立即读场景问题?【转】

在《醍醐灌顶!异地多活架构设计看这篇就够了》一文中,基于容灾需要,讨论了数据写入的架构模型。数据读取方面,重点在于解决读取请求的负载分担、路由选择的问题,对于容灾架构的选择影响不大。不过,其中的“写后立即读”场景,是个一致性范畴的问题,即写入的数据和写入后…

JAVA之面向对象

1、设计对象并使用类和对象 类(设计图):是对象共同特征的描述; 对象:是真实存在的具体实例; 在java中,必须先设计类,才能获得对象。 如何得到类的对象:类名 对象名 = new 类名(); 如何使用对象: 访问属性:对象名.成员变量 访问行为:对象名.方法…

免费手动打Windows Server补丁

免费手动打Windows Server 2008 R2补丁https://catalog.update.microsoft.com/search.aspx?q=kb4474419然后到windows上双击运行即可本文来自博客园,作者:六月OvO,转载请注明原文链接:https://www.cnblogs.com/chenlifan/p/18664077

pwn1_sctf_2016 1

打开ida反汇编看一下,是c++,无所谓,复制问一下ai先让我们输入s的数据,读取长度限制在32字节。然后replace函数会将s里面的 I 替换成 you 。最后输出s。 分析一下,s距离ebp为0x3C(60字节),且我们最多只能输入32字节的,但经过replace函数,一个字节的‘I’会被替换成三个…

UDS-ECU程序刷写

UDS(unified diagnostic services)统一诊断服务主要是针对汽车上对ECU进行诊断服务规范,下图是UDS在OSI分层中的具体规范,基于UDS的刷写应用逻辑体现在应用层的ISO14229规范。一、功能介绍 UDS(unified diagnostic services)统一诊断服务主要是针对汽车上对ECU进行诊断服…

主体分割技术,提升图像信息提取能力

在智能设备普及和AI技术进步的推动下,用户对线上互动的质量、个性化以及沉浸式体验的追求日益增强。例如,对于热衷于图片编辑或视频制作的用户来说,他们需要一种快速而简便的方法来将特定主体从背景中分离出来。 HarmonyOS SDK 基础视觉服务(Core Vision Kit)提供主体分割…