算法设计与分析——十大经典排序算法一(1--5)

news2024/11/26 7:45:01

目录

算法设计与分析——十大经典排序算法

第1关:冒泡排序

 参考代码

第2关:选择排序

参考代码

第3关:插入排序

 参考代码

第4关:希尔排序

参考代码

第5关:归并排序

 参考代码

作者有言


一个不知名大学生,江湖人称菜狗
original author: jacky Li
Email : 3435673055@qq.com

 Time of completion:2023.2.28
Last edited: 2023.2.28

导读:

帮助算法设计初学者快速掌握算法设计,帮助安静对ABCD……等的重要性排序更清晰!

算法设计与分析——十大经典排序算法

第1关:冒泡排序

任务描述

本关任务:实现冒泡排序算法,并将乱序数列变成升序。

相关知识

为了完成本关任务,你需要掌握:1.冒泡排序算法。

冒泡排序算法

冒泡排序重复地遍历待排序的数列,每次比较两个相邻元素,如果它们的顺序错误就把它们交换。重复地进行遍历直到没有再需要交换时表示数列已经排序完成。

  • 算法步骤:

    1. 比较相邻的元素:若第一个比第二个大,则交换;

    2. 遍历开始第一对到结尾最后一对,执行步骤1

    3. 重复步骤1~2,直到排序完成。

  • 可改进的冒泡排序:第一趟排序之后最后一个元素是最大的,因此下一趟遍历只需执行到倒数第二对。

编程要求

本关的编程任务是补全右侧代码片段sort_arrayBeginEnd中间的代码,具体要求如下:

  • sort_array中,实现冒泡排序算法,完成指定输出。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入:

10

7 1 4 6 8 9 5 2 3 10

预期输出:

1 4 6 7 8 5 2 3 9 10

1 4 6 7 5 2 3 8 9 10

1 4 6 5 2 3 7 8 9 10

1 2 3 4 5 6 7 8 9 10

测试输入:

15

3 44 38 5 47 15 36 26 27 2 46 4 19 50 48

预期输出:

3 38 5 44 15 36 26 27 2 46 4 19 47 48 50

3 5 38 15 36 26 27 2 44 4 19 46 47 48 50

3 5 15 36 26 27 2 38 4 19 44 46 47 48 50

2 3 4 5 15 19 26 27 36 38 44 46 47 48 50

 参考代码

#include "sort_.h"
 
void print_array(int *arr, int n)
{
    if(n==0){
        printf("ERROR: Array length is ZERO\n");
        return;
    }
    printf("%d", arr[0]);
    for (int i=1; i<n; i++) {
        printf(" %d", arr[i]);
    }
    printf("\n");
}
 
void sort_array(int *arr, int n)
{
    int i, x, j;
    for(j = 0; j < n; j ++)
    {
        for(i = 0; i < n - 1; i ++)
        {
            if(arr[i] > arr[i + 1]) 
            {
                x = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = x;
            }
        }
        if(j < 3) print_array(arr, n);
    }
    print_array(arr, n);
}

第2关:选择排序

任务描述

本关任务:实现选择排序算法,并将乱序数列变成升序。

相关知识

为了完成本关任务,你需要掌握:1.选择排序算法。

选择排序算法

选择排序是一种简单直观的排序算法,首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

  • 算法步骤:

    1. 初始状态:无序序列为R[0,n−1],长度n,有序区为空;

    2. 第i=1,..,n−1趟排序从当前无序区R[i−1,n−1]中选出最小的元素R[k],并将它与无序区的第1个记录R[i−1]交换,则R[0,i−1]变为元素个数增加1的新有序区,R[i,n−1]变为元素个数减少1的新无序区;

    3. n−1趟选择交换后结束。

编程要求

本关的编程任务是补全右侧代码片段sort_arrayBeginEnd中间的代码,具体要求如下:

  • sort_array中,实现选择排序算法,完成指定输出。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入:

10

7 1 4 6 8 9 5 2 3 10

预期输出:

1 7 4 6 8 9 5 2 3 10

1 2 4 6 8 9 5 7 3 10

1 2 3 6 8 9 5 7 4 10

1 2 3 4 5 6 7 8 9 10 

测试输入:

15

3 44 38 5 47 15 36 26 27 2 46 4 19 50 48

预期输出:

2 44 38 5 47 15 36 26 27 3 46 4 19 50 48

2 3 38 5 47 15 36 26 27 44 46 4 19 50 48

2 3 4 5 47 15 36 26 27 44 46 38 19 50 48

2 3 4 5 15 19 26 27 36 38 44 46 47 48 50

参考代码

#include "sort_.h"

void print_array(int *arr, int n)
{
    if(n==0){
        printf("ERROR: Array length is ZERO\n");
        return;
    }
    printf("%d", arr[0]);
    for (int i=1; i<n; i++) {
        printf(" %d", arr[i]);
    }
    printf("\n");
}

void sort_array(int *arr, int n)
{
    int len = n;
    int minIndex, temp;
    for (int i = 0; i < len - 1; i++) 
    {
        minIndex = i;
        for (int j = i + 1; j < len; j++) 
            if (arr[j] < arr[minIndex]) 
                minIndex = j;

        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
        if (i < 3) print_array(arr, n);
    }
    print_array(arr, n);
}

第3关:插入排序

任务描述

本关任务:实现插入排序算法,并将乱序数列变成升序。

相关知识

为了完成本关任务,你需要掌握:1.插入排序算法。

插入排序算法

插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  • 算法步骤:

    1. 从第一个元素开始,该元素认为已经被排序;

    2. 取下一个元素,在已经排序的元素序列中从后向前扫描;

    3. 如果已排序元素大于新元素,将已排序元素移到下一位置;

    4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

    5. 将新元素插入到该位置后;

    6. 重复步骤2~5

编程要求

本关的编程任务是补全右侧代码片段sort_arrayBeginEnd中间的代码,具体要求如下:

  • sort_array中,实现插入排序算法,完成指定输出。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入:

10

7 1 4 6 8 9 5 2 3 10

预期输出:

1 7 4 6 8 9 5 2 3 10

1 4 7 6 8 9 5 2 3 10

1 4 6 7 8 9 5 2 3 10

1 2 3 4 5 6 7 8 9 10

测试输入:

15

3 44 38 5 47 15 36 26 27 2 46 4 19 50 48

预期输出:

3 44 38 5 47 15 36 26 27 2 46 4 19 50 48

3 38 44 5 47 15 36 26 27 2 46 4 19 50 48

3 5 38 44 47 15 36 26 27 2 46 4 19 50 48

2 3 4 5 15 19 26 27 36 38 44 46 47 48 50

 参考代码

#include "sort_.h"

void print_array(int *arr, int n)
{
    if(n==0){
        printf("ERROR: Array length is ZERO\n");
        return;
    }
    printf("%d", arr[0]);
    for (int i=1; i<n; i++) {
        printf(" %d", arr[i]);
    }
    printf("\n");
}

void sort_array(int *arr, int n)
{
    int i, j, temp;
    for(i = 0; i < n - 1; i ++)
    {
        temp = arr[i + 1];
        j = i;
        while(j > -1 && temp < arr[j])
            arr[j + 1] = arr[j], j --;
        arr[j + 1] = temp;
        if (i < 3) print_array(arr, n);
    }
    print_array(arr, n);
}

第4关:希尔排序

任务描述

本关任务:实现希尔排序算法,并将乱序数列变成升序。

相关知识

为了完成本关任务,你需要掌握:1.希尔排序算法。

希尔排序算法

希尔排序由Shell在1959年发明,又叫缩小增量排序,是第一个突破O(n2)的排序算法,属于简单插入排序的改进版,会优先比较距离较远的元素。

  • 算法步骤:

    1. 选择一个增量序列T1​,T2​,… ,Tk​,其中Ti​>Tj​,Tk​=1,i>j;

    2. 每趟排序,根据对应的增量Ti​,将待排序列分割成若干子序列,分别对各子序列进行直接插入排序;

    3. 按增量序列个数k,对序列进行k趟排序。

  • 希尔排序实例: 下图的增量序列为:521,第一趟排序将增量为5的子序列进行插入排序,第二趟排序将增量为2的子序列进行插入排序,第三趟将增量为1的子序列进行插入排序,最终完成排序。

  • 希尔排序的核心在于增量序列的设定:

    既可以提前设定好增量序列,也可以动态的定义增量序列。例如序列长度为n,则动态增量为:147...3x+1<n/3

编程要求

本关的编程任务是补全右侧代码片段sort_arrayBeginEnd中间的代码,具体要求如下:

  • sort_array中,使用增量序列[5, 2, 1]实现希尔排序算法,完成指定输出。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入:

8

6 10 5 2 4 9 1 7

预期输出:

6 1 5 2 4 9 10 7

4 1 5 2 6 7 10 9

1 2 4 5 6 7 9 10

1 2 4 5 6 7 9 10

测试输入:

10

7 1 4 6 8 9 5 2 3 10

预期输出:

7 1 2 3 8 9 5 4 6 10

2 1 5 3 6 4 7 9 8 10

1 2 3 4 5 6 7 8 9 10

1 2 3 4 5 6 7 8 9 10

参考代码

#include "sort_.h"

void print_array(int *arr, int n)
{
    if(n==0){
        printf("ERROR: Array length is ZERO\n");
        return;
    }
    printf("%d", arr[0]);
    for (int i=1; i<n; i++) {
        printf(" %d", arr[i]);
    }
    printf("\n");
}

void sort_array(int *arr, int n)
{
    int i, j, m = 0;
    for(int gap = 5; gap > 0; gap /= 2) 
    {
        for(i = gap; i < n; i++) 
        {
            int num = arr[i];
            for(j = i - gap; j >= 0 && arr[j] > num; j -= gap)
                arr[j + gap] = arr[j];
            arr[j + gap] = num;
        }
        if(m < 3)
        {
            print_array(arr, n);
            m ++;
        }
    }
    print_array(arr,  n);
}

第5关:归并排序

任务描述

本关任务:实现归并排序算法,并将乱序数列变成升序。

相关知识

为了完成本关任务,你需要掌握:1.归并排序算法。

归并排序算法

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,是采用分治法Divide and Conquer的一个非常典型的应用。分Divide:将问题分成一些小的问题然后递归求解;治Conquer:将分的阶段得到的各答案合并在一起。

  • 算法步骤:

    1. 把长度为n的输入序列分成两个长度为n/2的子序列;

    2. 对这两个子序列分别采用归并排序;

    3. 将两个排序好的子序列合并成一个最终的排序序列。

编程要求

本关的编程任务是补全右侧代码片段merge_arraymerge_sortBeginEnd中间的代码,具体要求如下:

  • merge_array中,实现两个有序数组arr1arr2合并。
  • merge_sort中,实现归并排序:自上而下的递归方法。

测试说明

平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

以下是平台的测试样例:

测试输入:

10

7 1 4 6 8 9 5 2 3 10

预期输出:

1 2 3 4 5 6 7 8 9 10

测试输入:

15

3 44 38 5 47 15 36 26 27 2 46 4 19 50 48

预期输出:

2 3 4 5 15 19 26 27 36 38 44 46 47 48 50

 参考代码

#include "sort_.h"

void print_array(int *arr, int n)
{
    if(n==0){
        printf("ERROR: Array length is ZERO\n");
        return;
    }
    printf("%d", arr[0]);
    for (int i=1; i<n; i++)
        printf(" %d", arr[i]);
    printf("\n");
}

int* merge_array(int *arr1, int n1, int* arr2, int n2)
{
    int* res;
    res = new int[n1 + n2];
    int a1 = 0, a2 = 0, index = 0;
 
    for (int i = 0; i < n1+n2; i++) 
        if (i < n1) res[i] = arr1[i];
        else res[i] = arr2[i - n1];

    sort(res, res + n1 + n2);
    return res;
}

int* merge_sort(int *arr, int n)
{
    int mid = n / 2;
    if (mid > 0) 
    {
        int* arr1 = new int[mid];
        int n1 = mid, n2 = n - mid;
        int* arr2 = new int[n2];
        for (int i = 0; i < n; i++) 
            if (i < mid) arr1[i] = arr[i];
            else arr2[i - mid] = arr[i];
 
        merge_sort(arr1, n1);   
        merge_sort(arr2, n - mid);     
        merge_array(arr1, n1, arr2, n2);
    }
    else return  merge_array(arr, n, NULL, 0);
}

作者有言

如果感觉博主讲的对您有用,请点个关注支持一下吧,将会对此类问题持续更新……

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软考信息系统监理师备考建议

用好备考方法&#xff0c;两三个月就可以过的。信息系统监理师备考最好以教材和历年真题为主&#xff0c;教学视频模拟题为辅。考试介绍与复习建议&#xff1a;考试设置的科目包括&#xff1a;&#xff08;1&#xff09;信息系统工程监理基础知识&#xff0c;考试时间150分钟&a…

回顾1-idea创建Java项目

创建Java项目 创建项目和模块的区别 环境前置 IDEA开发工具JDK及配置环境变量 创建项目/工程 新建项目 选择Java模块 > SDK( 已配置的JDK ) > 下一步 直接下一步 填写项目信息 QQ游戏工程 里的 叫项目 所以 QQgame目录下 可以放 > 斗地主项目 / 美女来找茬等… …

Java调用C++方法(Linux下)

最近的项目中用到了java调用C的部分&#xff0c;记录一下&#xff0c;还是比较简单的。 所有需要的文件都放在同一个目录下。 java代码 public class NativeDemo {{System.load("/opt/java_c/src/NativeDemo.so");//这里必须用绝对路径}public native void SayHell…

Linux 进程:程序地址空间 与 虚拟内存

目录一、程序地址空间二、虚拟地址空间1.虚拟内存的原理2.使用虚拟内存的原因&#xff1f;3.如何实现虚拟空间&#xff1f;4.使用虚拟内存的好处本文主要介绍程序地址空间和虚拟地址空间的概念&#xff0c;理解了虚拟地址空间&#xff0c;才可以更好的理解物理内存和进程pcb之间…

scratch潜水 电子学会图形化编程scratch等级考试一级真题和答案解析2022年12月

目录 scratch潜水 一、题目要求 1、准备工作 2、功能实现 二、案例分析

# Redis 实战读书笔记(一)

Redis 实战读书笔记&#xff08;一&#xff09; 初始Redis ​ Redis是一个远程内存数据库&#xff0c;它不仅性能强劲而且还具有复制特性以及为解决问题而生的独一无二的数据模型。Redis提供了5中不同类型的数据库&#xff0c;初次之外通过复制持久化和客户端分片等特性用户可…

Android 项目必备(四十三)-->Android 开发者的 new 电脑

前言 作为 Android 开发者&#xff0c;当你新入职一家公司&#xff0c;拿到新发的电脑&#xff0c;你会对电脑干点啥&#xff1f; 安装开发环境&#xff1f;装软件&#xff1f;你是否还会铺天盖地到处找之前电脑备份的东西&#xff1f;又或者还想不起来有什么上一台电脑好用的…

一个9个月测试经验的人,居然在面试时跟我要18K,我都被他吓到了····

2月初我入职了深圳某家创业公司&#xff0c;刚入职还是很兴奋的&#xff0c;到公司一看我傻了&#xff0c;公司除了我一个测试&#xff0c;公司的开发人员就只有3个前端2个后端还有2个UI&#xff0c;在粗略了解公司的业务后才发现是一个从零开始的项目&#xff0c;目前啥都没有…

Mac iTerm2 rz sz

1、安装brew&#xff08;找了很多&#x1f517;&#xff0c;就这个博主的好用&#xff09; Mac如何安装brew&#xff1f;_行走的码农00的博客-CSDN博客_mac brew 2、安装lrzsz brew install lrzsz 检查是否安装成功 brew list 定位lrzsz的安装目录 brew list lrzsz 执…

【linux】:进程概念

文章目录 冯诺依曼体系结构一&#xff1a;操作系统二: 进程总结冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 冯诺依曼体系如下图&#xff1a; 那么输入设备有哪些呢&#xff1f…

时间复杂度和空间复杂度(1)

目录 1、算法效率 2、时间复杂度 1、定义 2、大O的渐进表示法 3、常见时间复杂度计算举例 3、空间复杂度 4、练习 例1、消失的数字 例2、旋转数组 1、算法效率 算法在编写成可执行程序后&#xff0c;运行时需要耗费计算机的时间资源和空间(内存)资源。因此衡量一个算法…

第八届蓝桥杯省赛——4承压计算(二维数组,嵌套循环)

题目&#xff1a;X星球的高科技实验室中整齐地堆放着某批珍贵金属原料。每块金属原料的外形、尺寸完全一致&#xff0c;但重量不同。金属材料被严格地堆放成金字塔形。7 5 8 7 8 8 9 2 7 2 8 1 4 9 1 8 1 8 8 4 1 7 9 6 1 4 5 4 5 6 5 5 6 9 5 6 5 5 4 7 9 3 5 5 1 7 5 7 9 7 4…

Unity 渲染流程管线

渲染流程图可以把它理解为一个流程&#xff0c;就是我们告诉GPU一堆数据&#xff0c;最后得出来一副二维图像&#xff0c;而这些数据就包括了”视点、三维物体、光源、照明模型、纹理”等元素。参考如下图(来自视频)CPU应用阶段剔除视锥剔除由Unity依据Camera直接完成&#xff…

PowerShell Install Tomcat

Tomcat 前言 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP 程序的首选。对于一个初学者来说&#xff0c;可以这样认为&#xff0c;当…

什么是百分比堆积条形图?

条形图实际上范围很广&#xff0c;它是以横置图形展示数据的一种图表类型。百分比堆积条形图即以堆积条形图的形式来显示多个数据序列&#xff0c;但是每个堆积元素的累积比例始终总计为 100%。它主要用于显示一段时间内的多项数据占比情况。 百分比堆叠条形图将多个数据集的条…

C++修炼之练气期一层——命名空间

目录 1.引例 2.命名空间的定义 3.命名空间的使用 4.命名空间使用注意事项 1.引例 #include <stdio.h> #include <stdlib.h>int rand 10;int main() {printf("%d\n", rand);return 0; } 当我们用C语言写下这样的代码&#xff0c;看着并没有什么语法…

Kubernetes06:Controller (Deployment无状态应用)

Kubernetes06:Controller 1、什么是controller 管理和运行容器的对象&#xff0c;是一个物理概念 在集群上管理和运行容器的对象 2、Pod和Controller之间的关系 Pod是通过controller来实现应用的运维 比如伸缩、滚动升级等等操作Pod和Controller之间通过 label 标签建立关系…

thread.join 是干什么的?原理是什么?

Thread.join 加了join&#xff0c;表示join的线程的修改对于join之外的代码是可见的。 代码示例&#xff1a; public class JoinDemo {private static int i 1000;public static void main(String[] args) {new Thread(()->{i 3000;}).start();System.out.println("…

C++学习笔记-异常处理

一个问题是程序在执行期间产生了一个例外。 C异常是一个特殊的情况在程序运行时&#xff0c;比如试图除以零而引致的响应结果。 异常提供一种方法来从一个程序到另一个程序的一个部分转移控制。 C异常处理建立在三个关键字&#xff1a; try, catch,和 throw。 throw: 程序抛出…

72. import 导入标准模块(os模块)

72. import 导入标准模块(os模块) 文章目录72. import 导入标准模块(os模块)1. 标准模块知识回顾2. os 模块的基本介绍3. import 导入标准模块1. 方法12. 方法21. 导包不同2. 声明不同3. 路径不同4. 概括3. 方法34. 方法44. 调用模块或库中的类、函数、变量5. os模块的路径操作…