《数据结构》--内部排序算法比较

2023-11-12

题目
各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。
基本要求:
(1) 从以下常用的内部排序算法至少选取5种进行比较:直接插入排序;折半折入排序;希尔排序;起泡排序;快速排序;简单选择排序;堆排序;归并排序。
(2) 待排序表的表长为20000;其中的数据要用伪随机数产生程序产生;至少要用5组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字移动次数(关键字交换计为3次移动)。

代码

#ifndef _HEAD_H
#define _HEAD_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX 20002
typedef int KeyType;
typedef int InfoType;
typedef struct SS
{
    KeyType key;   //关键字项
    InfoType data; //其他数据项
} RecType;         //排序的元素的类型

typedef struct SSS
{
    char name[30]; //排序名称
    int com;  //比较的次数
    int mov;  //移动的次数
}Analysis;    //存储分析效率的4数据


//交换函数
void swap(RecType &a, RecType &b)
{
    RecType c;
    c = a;
    a = b;
    b = c;
}
int compare = 0 , move = 0;  //关键字比较和移动的次数
Analysis Analy[5];             //五种算法的分析数据
//直接插入排序算法
//时间复杂度O(n^2)
void InsertSort(RecType R[], int n);
//折半插入排序法 
//把无序区插入到有序区里,由于前面的插入排序法实现了有序,所以直接在
//有序区利用折半查找来寻找的改进算法
void BinInsertSort(RecType R[], int n);
//希尔排序算法
void ShellSort(RecType R[], int n);
//冒泡排序算法
void BubbleSort(RecType R[], int n);
/*快速排序算法*/
int partition(RecType R[], int s, int t); //一趟划分
//对R[s..t]的元素进行快速排序
void QuickSort(RecType R[], int s, int t);
//菜单
void menu();
//调用直接插入排序的实现函数,即菜单1
void FirstFun(RecType a[], int n);
//菜单2
void SecondFun(RecType a[], int n);
//菜单3
void ThirdFun(RecType a[], int n);
//菜单4
void FourthFun(RecType a[], int n);
//菜单5
void FifthFun(RecType a[], int n);
//菜单6
void SixthFun(RecType a[], int n);
#endif

//五种常见的算法
///
//直接插入排序算法
//时间复杂度O(n^2)
void InsertSort(RecType R[], int n)
{
    int i, j;
    RecType tmp;

    for (i = 1; i < n; i++)    //for循环内一定比较了n-1次,if判断语句
    {
        if (R[i].key < R[i - 1].key) //一旦出现了逆序的关键字,就进行插入
        {
            tmp = R[i];
            j = i - 1;
            compare++;
            do    //往后移动一个位置,腾空间给tmp;
            {
                R[j + 1] = R[j];
                move++;    //移动加一
                j--;
                compare++; //比较次数加一
            } while (j >= 0 && R[j].key > tmp.key);

            R[j + 1] = tmp; //最后把tmp放在对应的位置
            move+=2; //移动的temp
        }
    }
    
}

//折半插入排序法 
//把无序区插入到有序区里,由于前面的插入排序法实现了有序,所以直接在
//有序区利用折半查找来寻找的改进算法
void BinInsertSort(RecType R[], int n)
{
    int i, j, low, high, mid;
    RecType tmp;

    for (i = 1; i < n; i++)  //已经比较了n-1次
    {
        if (R[i].key < R[i - 1].key)
        {
            tmp = R[i];
            low = 0;
            high = i - 1;
            
            compare++;

            while (low <= high)  
            {
                compare++;  //while进入比较
                mid = (low + high) / 2;
                if (tmp.key < R[mid].key)
                    high = mid - 1;
                else
                    low = mid + 1;
            }

            for (j = i - 1; j >= high + 1; j--)
            {      
                R[j + 1] = R[j];
                move++;//移动次数加一
            }
            R[high + 1] = tmp;
            move += 2;//tmp交换
        }
    }

}
///
//希尔排序算法
void ShellSort(RecType R[], int n)
{
    int i, j, d;
    RecType tmp;
    d = n / 2;

    while (d > 0)
    {
        for (i = d; i < n; i++)
        {
            tmp = R[i];
            j = i - d;

            while (j >= 0 && tmp.key < R[j].key)
            {
                compare++;
                move++;
                R[j + d] = R[j];
                j = j - d;
            }
            R[j + d] = tmp;
            move += 2;//tmp进行两次操作
        }
        d = d / 2;
    }
}
///
//冒泡排序算法
void BubbleSort(RecType R[], int n)
{
    int i, j;
    bool exchange;
    RecType tmp;

    for (i = 0; i < n - 1; i++)
    {
        exchange = false;

        for (j = n - 1; j > i; j--)
            if (R[j].key < R[j - 1].key)
            {
                compare ++;
                move += 3;
                tmp = R[j - 1];
                R[j - 1] = R[j];
                R[j] = tmp;
                exchange = true;
            }

        if (!exchange)
            return;
    }
}
/
/*快速排序算法*/
int partition(RecType R[], int s, int t) //一趟划分
{
    int i = s, j = t;
    RecType tmp = R[i]; //以R[i]为基准
    while (i < j)       //从两端交替向中间扫描,直至i=j为止
    {
        while (j > i && R[j].key >= tmp.key)
        {
                j--;     //从右向左扫描,找一个小于tmp.key的R[j]
                compare++;//进行比较
        }
        R[i] = R[j]; //找到这样的R[j],放入R[i]处
        move++;      //移动+1
        while (i < j && R[i].key <= tmp.key)
        {    i++;      //从左向右扫描,找一个大于tmp.key的R[i]
             compare++;//比较加一
        }
        R[j] = R[i]; //找到这样的R[i],放入R[j]处
        move++;      //移动加一
    }
    R[i] = tmp;
    move+=2; //temp的交换
    return i;
}

void QuickSort(RecType R[], int s, int t)
//对R[s..t]的元素进行快速排序
{
    int i;
    if (s < t) //区间内至少存在两个元素的情况
    {
        i = partition(R, s, t);
        QuickSort(R, s, i - 1); //对左区间递归排序
        QuickSort(R, i + 1, t); //对右区间递归排序
    }
}
/

void menu()
{
    printf("***************************************************\n");
    printf("\t\t1.直接插入排序法\n");
    printf("\t\t2.折半插入排序法\n");
    printf("\t\t3.希尔排序法\n");
    printf("\t\t4.冒泡排序法\n");
    printf("\t\t5.快速排序法\n");
    printf("\t\t6.效率比较\n");
    printf("\t\t7.退出\n");
    printf("***************************************************\n");
}


//调用直接插入排序的实现函数,即菜单1
void FirstFun(RecType a[], int n)
{
     int i;
     for (i = 0; i < MAX; i++)
        a[i].key = rand() % 100;
    printf("伪随机数生成的20002个随机数:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
        putchar(10);
    
    InsertSort(a, MAX);

    printf("\n\n\n利用直接插入排序后的数列如下:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
    
    printf("\n\n直接插入排序法:\n一共比较了%d次,移动了%d次\n",compare,move);
    Analy[0].com = compare;
    Analy[0].mov = move;
    strcpy(Analy[0].name, "直接插入排序");
}
//菜单2
void SecondFun(RecType a[], int n)
{
    int i;
     for (i = 0; i < MAX; i++)
        a[i].key = rand() % 100;
    printf("伪随机数生成的20002个随机数:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
        putchar(10);

    compare = 0;
    move = 0;
    BinInsertSort(a, MAX);

    printf("\n\n\n利用折半插入排序后的数列如下:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
    
    printf("\n\n折半插入排序:\n一共比较了%d次,移动了%d次\n",compare,move);
    Analy[1].com = compare;
    Analy[1].mov = move;
    strcpy(Analy[1].name, "折半插入排序");
}

//菜单3
void ThirdFun(RecType a[], int n)
{
    int i;
     for (i = 0; i < MAX; i++)
        a[i].key = rand() % 100;
    printf("伪随机数生成的20002个随机数:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
        putchar(10);

    compare = 0;
    move = 0;
    ShellSort(a,MAX);

        printf("\n\n\n利用希尔排序算法后的数列如下:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
    
    printf("\n\n希尔排序算法:\n一共比较了%d次,移动了%d次\n",compare,move);
    Analy[2].com = compare;
    Analy[2].mov = move;
    strcpy(Analy[2].name, "希尔排序算法");
}
//菜单4
void FourthFun(RecType a[], int n)
{
     int i;
     for (i = 0; i < MAX; i++)
        a[i].key = rand() % 100;
    printf("伪随机数生成的20002个随机数:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
        putchar(10);

    compare = 0;
    move = 0;
    BubbleSort(a,MAX);

     printf("\n\n\n利用冒泡排序法后的数列如下:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
    
    printf("\n\n冒泡排序算法:\n一共比较了%d次,移动了%d次\n",compare,move);
    Analy[3].com = compare;
    Analy[3].mov = move;
    strcpy(Analy[3].name, "冒泡排序算法");
}
//菜单5
void FifthFun(RecType a[], int n)
{
    int i;
     for (i = 0; i < MAX; i++)
        a[i].key = rand() % 100;
    printf("伪随机数生成的20002个随机数:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');
        putchar(10);
    
    compare = 0;
    move = 0;
    QuickSort(a,0,MAX);
         printf("\n\n\n利用快速排序算法后的数列如下:\n\n\n");
    for (i = 0; i < MAX; i++)
        printf("%3d%c", a[i].key, (i + 1) % 20 ? ' ' : '\n');

    printf("\n\n快速排序算法:\n一共比较了%d次,移动了%d次\n",compare,move);
    Analy[4].com = compare;
    Analy[4].mov = move;
    strcpy(Analy[4].name, "快速排序算法");
}
//菜单6
void SixthFun(RecType a[], int n)
{
    int i;
    printf("各种排序算法的比较于移动次数的对比:\n\n");
    //printf("   名称\t\t\t\t比较次数\t\t\t移动次数\n");
    printf("   名称          比较次数          移动次数\n");

    for(i = 0; i < 5; i++)
        printf("%-17s%-18d%d\n",Analy[i].name,Analy[i].com,Analy[i].mov);
}

int main ()
{
    RecType a[MAX];
    int i, k;
    srand((unsigned)time(NULL));
    menu();
    printf("请选择操作:");
    scanf("%d",&k);

    while(k!=7)
    {
        switch(k) {
            case 1:  FirstFun(a,MAX);  break;
            case 2:  SecondFun(a,MAX); break;
            case 3:  ThirdFun(a,MAX);  break;
            case 4:  FourthFun(a,MAX); break;
            case 5:  FifthFun(a,MAX);  break;
            case 6:  SixthFun(a,MAX);  break;
            default:   break;
        }
        
        system("pause");
        system("cls");
        menu();
        printf("请选择操作:");
        scanf("%d",&k);

    }


    system("pause");
    return 0;
}

运行结果
结果如图所示
记得点赞啊!!
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《数据结构》--内部排序算法比较 的相关文章

随机推荐

  • 升级openssl后nginx无法编译安装问题之解决方法

    Linux下升级openssl到新版本 如CentOS 7中openssl升级到openssl 1 1 1d 后 其实原nginx并没有真正调用新的openssl 1 1 1d 怎么办呢 需对nginx重新编译 但在编译安装过程中有人就无法
  • 利用Console来调试JS程序、Console用法总结

    利用Console来调试JS程序 Console用法总结 1 一 什么是 Console Console 是用于显示 JS和 DOM 对象信息的单独窗口 并且向 JS 中注入1个 console 对象 使用该对象 可以输出信息到 Conso
  • 零基础小白-自学java全栈开发-学习路线-只要看这一篇就可以了(完整版)

    文章目录导航 小白自述 具体内容以及详细流程 开发工具的使用 总结一下 什么是java 第一个java程序分析 基础知识 运算符操作 控制语句 数组类型 方法定义和使用 Eclipse工具的使用 类与对象 常用类 集合类 内部类 异常处理
  • pikachu靶场RCE的学习

    RCE remote command code execute RCE的概述 RCE漏洞 可以让攻击者直接向后台服务器远程注入操作系统命令或者代码 从而控制后台系统 RCE的分类 ping Ping Packet Internet Grop
  • AI智慧,书香飘溢

    如果有天堂 天堂应该是图书馆的模样 阿根廷国家图书馆前馆长 著名作家博尔赫斯如此形容图书馆 人类文明的演进与传承 倚仗于知识的积累 而知识的载体往往绕不开书籍 其集散地 图书馆 更是在这一过程扮演着极为重要的角色 早在公元前3000年 亚述
  • 75.android 简单的获取当前可用运行内存,总运行内存,获取包含系统软件在内的所有内存,获取系统参数显示的内存大小。

    1 获取手机系统参数显示的内存大小 RAM内存大小 返回1GB 2GB 3GB 4GB 8G 16G return public static String getTotalRam String path proc meminfo Stri
  • cryptographic primitives(密码学原语 )

    hash commitment Pedersen承诺
  • 返回json带转义符时的处理方法Content-Type: text/plain;

    当从json文件中读取json数据返回前端时 Content Type不同会导致返回给前端的数据结构也不同 Content Type text plain charset UTF 8 text plain的意思是将文件设置为纯文本的形式 浏
  • SQL删除重复数据只保留一条

    用SQL语句 删除掉重复项只保留一条 在几千条记录里 存在着些相同的记录 如何能用SQL语句 删除掉重复的呢1 查找表中多余的重复记录 重复记录是根据单个字段 peopleId 来判断 select from people where pe
  • vue 孙组件给父组件传值

    1 在孙组件里定义事件 通过 emit把值传出去 孙组件 planPop vue
  • unity键盘按键版垃圾分类

    有个键盘控制版的垃圾分类 打开程序后按任意键进行游戏 共分为可回收垃圾 厨余垃圾 有害垃圾 其他垃圾 游戏时间一共60s 按1 2 3 4分别会使垃圾到对应的垃圾桶 放对垃圾就会打开垃圾桶 放错垃圾桶会有放错提示 60s后会计算成绩 按任意
  • JS逆向新技术--JSRPC

    声明 本文章中所有内容仅供学习交流 不可用于任何商业用途和非法用途 否则后果自负 如有侵权 请联系作者立即删除 由于本人水平有限 如有理解或者描述不准确的地方 还望各位大佬指教 介绍 JSRPC意思就是远程调用js代码 全称 Remote
  • java树形数据结构递归求上级,附答案

    Part 1微服务架构设计概述 1 1 传统应用架构的问题 1 2 微服务架构是什么 1 3 微服务架构有哪些特点和挑战 1 4 如何搭建微服务架构 Part 2微服务开发框架 2 1 Spring Boot 是什么 2 2 如何使用Spr
  • sql注入利用union来绕过括号过滤

    union盲注 当我们在括号被过滤的时候 就不能使用substr mid 等多种函数 于是想到union 要想知道uinon的怎么进行盲注 就要了解union 这里给大家看几个mysql的查询语句 通过这三条语句我们可以看到 我们我利用un
  • STM32自定义printf功能方法

    最近在朋友那学到了如何重定义STM32的printf类似函数 在这做下记录 调用C语言库函数文件具体是哪一个我忘记了 都加上吧 include
  • ps制作鲨鱼在橙子“海洋”里游泳的创意画面

    预览效果 1 新建画布725X450 打开素材 把橘子放进去 并且把中间部分用钢笔工具抠出来 操作 1 使用钢笔工具在 橘子果肉的边缘点击 形成闭合路径 2 按ctrl 回车键 将其变成选区 蚂蚁线 3 将选区 存储起来 2 将水面素材拖入
  • 学习大数据必须掌握的核心技术概念

    随着数字化时代的到来 大数据成为了各行各业的关键资源 学习大数据的核心技术概念是成为一名优秀数据专家的关键 本文将介绍几个大数据的核心技术概念 并提供相应的源代码示例 帮助读者更好地理解和应用这些概念 分布式存储和处理 在大数据领域 数据量
  • CentOS7 安装 NVIDIA Container Toolkit

    安装containerd io sudo yum install y https download docker com linux centos 7 x86 64 stable Packages containerd io 1 4 3 3
  • vue遍历Map,Map在vue中的使用方法

    Map在vue中的使用方法 html 遍历的时候要遍历两遍
  • 《数据结构》--内部排序算法比较

    题目 各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶 或大概执行时间 试通过随机的数据比较各算法的关键字比较次数和关键字移动次数 以取得直观感受 基本要求 1 从以下常用的内部排序算法至少选取5种进行比较 直接插入排序 折半折