【数据结构实验】排序(三)快速排序算法的改进(三者取中法)

news/2024/5/19 22:35:35 标签: 数据结构, 排序算法, 算法, c语言, 快速排序

文章目录

  • 1. 引言
  • 2. 快速算法>排序算法
  • 3. 实验内容
    • 3.1 实验题目
      • (一)输入要求
      • (二)输出要求
    • 3.2 算法实现
  • 4. 实验结果

1. 引言

  快速排序是一种经典的算法>排序算法,其核心思想是通过选择一个基准元素,将数组分为两个部分,左边的元素小于基准,右边的元素大于基准,然后对左右两部分递归地进行排序。然而,在处理基本有序数组时,传统的快速排序可能会退化为 O ( n 2 ) O(n^2) O(n2)的时间复杂度。为了解决这个问题,引入了三者取中法,通过选择数组中的三个元素并取其中值作为基准元素,能够在基本有序的情况下提高排序效率。

2. 快速算法>排序算法

2.1 传统快速排序

  快速排序的核心思想是通过选择一个基准元素,将待排序的数组划分为两个部分,左边的元素小于基准,右边的元素大于基准,然后对左右两部分递归地进行排序,其时间复杂度:

  1. 最好情况: 每次分划都能将数组平均地划分成两部分,此时的时间复杂度为 O ( n l o g 2 n ) O(n log_2 n) O(nlog2n)
  2. 最坏情况: 每次分划都选择了数组中最小(或最大)的元素作为基准,导致每次分划只能减少一个元素,时间复杂度 O ( n 2 ) O(n^2) O(n2)
  3. 平均情况: 通过概率分析,可以证明时间复杂度为 O ( n l o g 2 n ) O(n log_2 n) O(nlog2n)

2.2 三者取中法

2. 算法描述:
  改进的快速算法>排序算法主要区别在于基准元素的选择。在传统快速排序中,通常选择随机元素作为基准,而在改进算法中则采用三者取中法:
在这里插入图片描述
在这里插入图片描述

3. 实验内容

3.1 实验题目

  实现教材233 页下方提及的 Select 算法(求第 4 小元素)(要求文件长度大于等于 5 时调用 Partition2 算法,否则调用直接插入算法>排序算法)。

(一)输入要求

第一组输入数据:
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
第二组输入数据:
{16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}

(二)输出要求

对每组输入数据,输出以下信息(要求必须要有关于输出数据的明确的提示信息)

  1. 输出分划次数;
  2. 输出找到第 4 小元素时文件的状态,即输出此时所有记录的值。

3.2 算法实现

#include<stdio.h>
void Change(int R[],int i,int j)
{
    int t=R[i];
    R[i]=R[j];
    R[j]=t;
}
int Partition2(int R[],int m,int n)
{
    Change(R,(m+n)/2,m+1);
    if(R[m+1]>R[n]) Change(R,m+1,n);
    if(R[m]>R[n]) Change(R,m,n);
    if(R[m+1]>R[m]) Change(R,m + 1,m);
    int i=m,j=n+1,K=R[m];
    while(i<j)
    {
        i++;
        while(R[i]<=K) i++;
        j--;
        while(R[j]>K) j--;
        if(i<j)
            Change(R,i,j);
    }
    Change(R,m,j);
    return j;
}
void InsertSort(int R[],int len)
{
    int i,j,t;
    for(i=1;i<len;i++)
        if(R[i]<R[i-1])
        {
            t=R[i];
            R[i]=R[i-1];
            for(j=i-1;R[j]>t&&j>=0;j--){
                R[j+1]=R[j];
            }
            R[j+1]=t;
        }
}
int Select(int R[], int n)
{
    if(n>=5){
        int t=Partition2(R,1,n),rounds=0;
        rounds++;
        while(t!=4){
            if(t<4) t=Partition2(R,t+1,n);
            else t=Partition2(R,1,t-1);
            rounds++;
        }
        printf("分划次数为%d次\n",rounds);
        printf("找到第4小元素时文件状态为:");
        int i;
        for(i=0;i<n;i++)
            printf("%d ",R[i]);
        printf("\n");
        return R[4];
    }
    else{
        InsertSort(R,n);
        return R[4];
    }
}
int main()
{
    //int R[16]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    int R[16]={16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
    printf("第4小元素为%d",Select(R,16));
    return 0;
}


  1. Change 函数用于交换数组中的两个元素。
  2. Partition2 函数使用中值法选择主元,并使用修改过的Lomuto分区方案对数组进行分区。它返回选择的主元的最终位置。
  3. InsertSort 函数对数组执行插入排序。
  4. Select 函数是主要的算法。如果数组的大小大于或等于5,它使用Partition2 函数递归地找到第4小元素。如果大小小于5,它使用 InsertSort 函数对数组进行排序,并返回第4个元素。

4. 实验结果

在这里插入图片描述

在这里插入图片描述


http://www.niftyadmin.cn/n/5214303.html

相关文章

5.1每日一题(无穷级数敛散性的判断:莱布尼兹准则、p级数、绝对收敛、条件收敛、比较法/比较法的极限形式)

莱布尼兹准则&#xff1a;&#xff08;1&#xff09;单调递减&#xff1b;&#xff08;2&#xff09;极限 -> 0 绝对收敛&#xff1a;级数的绝对值收敛 条件收敛&#xff1a;级数的绝对值发散 p级数的次幂 <1 时发散 &#xff1b;>1时收敛

微服务实战系列之Nginx(技巧篇)

前言 今天北京早晨竟然飘了一些“雪花”&#xff0c;定睛一看&#xff0c;似雪非雪&#xff0c;像泡沫球一样&#xff0c;原来那叫“霰”。 自然中&#xff0c;雨雪霜露雾&#xff0c;因为出场太频繁&#xff0c;认识门槛较低&#xff0c;自然不费吹灰之力&#xff0c;即可享受…

JAVA之异常详解

1. 异常的概念与体系结构 1.1 异常的概念 在Java中&#xff0c;将程序执行过程中发生的不正常行为称为异常 1. 算术异常 public class Test {public static void main(String[] args) {System.out.println(10/0);} } 因为 0 不能当被除数&#xff0c;所以报出了异常&#…

记一次Java应用查询不到最新数据的问题

第一次项目上线前,生产环境调试阶段,项目经理反馈在备机房所在环境验证时报错,id不存在。 我赶紧去排查,查看日志,发现日志里打印的id是旧数据记作1,拿着这个数据去调其他系统提示id不存在。 查看配置表里id是新的,暂且叫2吧,就很奇怪,查看代码,直接查库,然后打印…

暴雷!Shopee佣金再度上调,入驻还需要保证金?—站斧浏览器

近段时间以来&#xff0c;Shopee陆陆续续地上调了多个站点地佣金费率、交易手续费以及FSS&CCB费率等&#xff0c;不仅如此&#xff0c;Shopee还官宣了入驻需要缴纳保证金&#xff01;甚至已入驻商家未交保证金或会被冻结风险&#xff01;这一些列操作让不少Shopee卖家有些措…

⑦【Redis GEO 】Redis常用数据类型:GEO [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Redis GEO ⑦Redis GEO 基本操作命令1.geoadd …

国标交流充电桩接口和直流充电桩接口介绍

1、背景 与传统油车相比&#xff0c;纯电车有太多的优势&#xff0c;但是纯电需要考虑充电时间的长短以及电池的使用寿命。然而相比较而言&#xff0c;混动有好多的备选方案比如插电式、增程式等&#xff0c;除了满足比电车较远的续航外&#xff0c;充电等待时间大大缩短。 在…

【C++】泛型编程 ⑮ ( 类模板示例 - 数组类模板 | 自定义类中持有指针成员变量 )

文章目录 一、支持 数组类模板 存储的 自定义类1、可拷贝和可打印的自定义类2、改进方向3、改进方向 - 构造函数4、改进方向 - 析构函数5、改进方向 - 重载左移运算符6、改进方向 - 重载拷贝构造函数 和 等号运算符 二、代码示例1、Array.h 头文件2、Array.cpp 代码文件3、Test…