排序法 C语言常考的十大排序法 数列、字符的排序

2023-11-08

通过对近各大试卷题型分析,总结出 对于数据排序的十大方法,希望对大家有所帮助

方法一:冒泡排序法(升序排序法)

方法二:选择排序法

方法三:插入排序法

方法四:希尔排序法(Shell Sort)

方法五:归并排序法

方法六:快速排序法(交换排序法)

方法七:堆排序法

方法八:计数排序法

方法九:桶排序法

方法十:基数排序法

1.冒泡排序法

1.1 算法描述
步骤1: 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
步骤2: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应               该会是最大的数;
步骤3: 针对所有的元素重复以上的步骤,除了最后一个;
步骤4: 重复步骤1~3,直到排序完成。

冒泡排序法动画演示

(1)对数列的排序:

#include <stdio.h>
#define sequence 10//自定义十个元素的数列
int main()
{
    int a[sequence] = {12,43,9,13,67,98,101,89,3,35 };//十个数的无序数列
                                                      //也可以改为用scanf输入
    int i, j, t;
    printf("此程序使用冒泡排序法排列无序数列!\n");
    //冒泡排序
    for (i = 0; i < 10 - 1; i++)//n个数的数列总共扫描n-1次
    {
        for (j = 0; j < 10 - i - 1; j++)//每一趟扫描到a[n-i-2]与a[n-i-1]比较为止结束
        {
            if (a[j] > a[j + 1])//后一位数比前一位数小的话,就交换两个数的位置(升序)
            {
                t = a[j + 1];
                a[j + 1] = a[j];
                a[j] = t;
            }
        }
    }
    printf("排列好的数列是:\n");
    //输出排列好得吃数列
    for (i = 0; i < 10; i++)
    {
        printf("%d ", a[i]);
    }
    return 0;
}

运行结果如下:

(2)对字符的排序

#include <stdio.h>
#define Character_groups 10//定义了十个字符的字符数组
int main()
{
    char a[Character_groups] = { 'i','l','o','v','e','y','o','u','y','x' };//十个数的无序数列  
   //也可以改用scanf函数输入字符
    int i, j;
    char t;
    printf("此程序使用冒泡排序法排列无序数列!\n");
    //冒泡排序
    for (i = 0; i < 10 - 1; i++)//n个数的数列总共扫描n-1次
    {
        for (j = 0; j < 10 - i - 1; j++)//每一趟扫描到a[n-i-2]与a[n-i-1]比较为止结束
        {
            if (a[j] > a[j + 1])//后一位数比前一位数小的话,就交换两个数的位置(升序)
            {
                t = a[j + 1];
                a[j + 1] = a[j];
                a[j] = t;
            }
        }
    }
    printf("排列好的字符组是:\n");
    //输出排列好得吃数列
    for (i = 0; i < 10; i++)
    {
        printf("%c ", a[i]);
    }
    return 0;
}

运行结果如下:

     

           对字符串的排序----(自定义函数的方法实现)

#include <stdio.h>

void function(char a[], int m)
{
    //冒泡排序
    int i, j;
    char tmp;
    for (i = 0; i < m - 1; i++)//n个数的数列总共扫描n-1次
    {
        for (j = 0; j < m - i - 1; j++)//每一趟扫描到a[n-i-2]与a[n-i-1]比较为止结束
        {
            if (a[j] > a[j + 1])//后一位数比前一位数小的话,就交换两个数的位置(升序)
            {
                tmp = a[j + 1];
                a[j + 1] = a[j];
                a[j] = tmp;
            }
        }
    }
    return;
}

int main()
{
    void function(char a[], int);//尤其注意,此处的函数声明必须是char a[],因为这里穿的是地址,不能仅仅使用char
    int i;
    char a[10] = { 'i','l','o','v','e','y','o','u','y','x' };//十个数的无序字符数列
    printf("此程序使用冒泡排序法排列无序数列!\n");
    function(a, 10);//调用冒泡排序
    printf("排列好的字符组是:\n");
    //输出排列好得吃数列
    for (i = 0; i < 10; i++)
    {
        printf("%c ", a[i]);
    }
    return 0;
}

运行结果如下:

2.选择排序法

步骤1:初始状态:无序区为R[1…n],有序区为空;
步骤2:第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1…i-1]和R(i…n)。该趟排              序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使                    R[1…i]和R[i+1…n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
步骤3:n-1趟结束,数组有序化了。

选择排序法动画演示

两层for循环实现 

#include <stdio.h>

int main()
{
    int i, j, k, n, tmp, a[1000];
    printf("请输入需要排序的数据个数\n");
    scanf("%d",&n);// 从键盘输入待排序的数据个数
    for (i = 0; i < n; i++) 
    { // 利用for循环依次将输入的数据放置在数组中
        scanf("%d",&a[i]);
    }
    for (i = 0; i < n - 1; i++) 
    {// 外层循环 变量i控制排序总共进行n-1轮
        k = i;
        for (j = i + 1; j < n; j++) 
        { //内层循环 变量j控制每轮进行比较的次数
            if (a[j] < a[k])
            {
                k = j;   //k记录每轮比较中的最小者的下标
                if (k != i) 
                { //将第i轮的最小者,与a[i]交换
                    tmp = a[i];
                    a[i] = a[k];
                    a[k] = tmp;
                }
            }
        }
    }
    printf("排序后的数据如下:\n");
    for (i = 0; i < n; i++) { // 利用for循环进行输出
        printf("%d\t", a[i]);
    }
    return 0;
}

     运行结果如下:

   自定义函数的方法实现

#include<stdio.h>

void SelectSort(int a[], int n) 
{ //选择排序
    int mix, tmp;
    int i, j;
    for (i = 0; i < n - 1; i++) 
    { //每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
        mix = i; //假设最小元素的下标
        for (j = i + 1; j < n; j++) //将上面假设的最小元素与数组比较,交换出最小的元素的下标
            if (a[j] < a[mix])
                mix = j;
        //若数组中真的有比假设的元素还小,则交换
        if (i != mix) 
        {
            tmp = a[i];
            a[i] = a[mix];
            a[mix] = tmp;
        }
    }
}

int main()
{
    int a[10] = { 9,1,5,8,3,7,4,6,2,0 };
    int i;
    SelectSort(a, 10);
    for (i = 0; i < 10; i++)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

 运行结果如下:

指针传参方法实现:

#include<stdio.h>
//指针方法实现十个整数的排序
int main()
{
    void sort(int x[], int n);//函数的声明
    int i, * p, a[10];//定义i,*p,数组a
    p = a;//把首元素的地址赋值给指针变量p
    printf("please enter 10 integer numbers:");
    for (i = 0; i < 10; i++)
    {
        scanf("%d", p++);//将从数组的每一个元素的地址都存到内存当中去
    }
    p = a;//再次将指针p指向首元素的地址
    sort(p, 10);//函数的调用

    for (p, i = 0; i < 10; i++)//输出语句    可以写p=a;或者直接写p
    {
        printf("%d ", *p);
        p++;
    }
    printf("\n");
    return 0;
}

void sort(int x[], int n)
{
    int i, j, k, t;
    for (i = 0; i < n - 1; i++)//外层循环控制比较的总趟数  n-1趟
    {
        k = i;//第一次先将下标0对应的元素作为最大元素的下标
        for (j=i+1; j < n ; j++)//内层循环控制每趟比较的总次数
        {
                if (x[j] > x[k])
                {
                    k = j; //k始终保存最大值元素的下标
                }    
        if(k!=i)//如果最大值元素的下标不是最前面的i,则交换元素值
        {
            t = x[i];
            x[i] = x[k];
            x[k] = t;
        }
            }
    }
}

代码运行结果如下:

3.插入排序法

步骤1: 从第一个元素开始,该元素可以认为已经被排序;
步骤2: 取出下一个元素,在已经排序的元素序列中从后向前扫描;
步骤3: 如果该元素(已排序)大于新元素,将该元素移到下一位置;
步骤4: 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
步骤5: 将新元素插入到该位置后;
步骤6: 重复步骤2~5。

插入排序法动画演示

(1)简单方法实现 

#include<stdio.h>
#include<string.h>
#define sequence 5
void insertSort(int a[])
{
    int i, j, temp;
    for (i = 1; i < sequence; i++)
    {
        temp = a[i];
        //当前数小于前一位数时
        if (a[i] < a[i - 1])
        {
            //将子序列重新排列为有序序列
            for (j = i - 1; temp < a[j]; j--)
            {
                a[j + 1] = a[j];
            }
            a[j + 1] = temp;
        }
    }
}
int main()
{
    int a[] = { 45,32,56,71,12 };
    int i;
    printf("未排序前:\n");
    for (i = 0; i < sequence; i++)
    {
        printf("%d  ", a[i]);
    }
    printf("\n经过直接插入排序后:\n");
    insertSort(a);
    for (i = 0; i < sequence; i++)
    {
        printf("%d  ", a[i]);
    }
    return 0;
}

 运行结果如下:

 (2)自定义函数方法实现

#include <stdio.h>

void print(const int* a, const int length)
{
    int i;
    for (i = 0; i < length; i++) 
    {
        printf("%d ", a[i]);
    }
    putchar('\n');
}

void pushFront(int* a, const int length, const int key)
{
    //将所有a[j]到a[length]都往后推一格
    int tmp = a[length];
    for (int i = length; i > key; i--)
    {
        a[i] = a[i - 1];
    }
    a[key] = tmp;
}

void insertSort(int* a, const int length)
{
    for (int i = 0; i < length; i++)
    {
        for (int j = 0; j < i; j++)
        {
            if (a[i] < a[j])
            {
                pushFront(a, i, j);
                break;
            }
        }
        print(a, i + 1);
    }
}

int main() 
{
    const int length = 5;
    int my_array[5] = { 1,5,4,3,7 };
    print(my_array, length);
    insertSort(my_array, length);
    return 0;
}

     运行结果如下:

 (3)折半插入排序法实现

#include<stdio.h>
#define N 10

//对数组a进行折半插入排序,n为数组的长度;
void Half_Sort(int a[])
{
    for (int i = 1; i < N; i++)
    {
        int x = a[i];   //将需要进行插入排序的元素赋值给x;
        int low = 0, high = i - 1;  //设置折半的头和尾;
        while (low <= high)
        {
            int mid = (low + high) / 2;  //设置中间元素,与插入的元素进行比较;
            if (x < a[mid])   //比较;
                high = mid - 1;
            else
                low = mid + 1;
        }
        for (int j = i - 1; j >= low; j--)  //记录依次向后移;
            a[j + 1] = a[j];   //将当前这个值赋给这个元素的后一个元素;
        a[low] = x;   //插入记录;
    }
}

int main()
{
    int a[N] = { 3,2,8,5,4,7,6,9,1,10 };  //定义数组;
    printf("原始数据为:\n");
    for (int i = 0; i < N; i++)  //输出原始数据;
        printf("%d ", a[i]);
    printf("\n\n");

    Half_Sort(a);
    printf("使用插入排序后的数据为:\n");
    for (int i = 0; i < N; i++)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

运行结果如下:

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

排序法 C语言常考的十大排序法 数列、字符的排序 的相关文章

随机推荐

  • C++实现链表合并

    include
  • 2023华为OD机试python【代表团坐车】

    前言 本答案使用python解答 如果需要Java版本题解 请参考 Java版本 题目 现在要组织一场活动 有多个代表团需要参加活动 已知多个代表团同时到达 但是接待处可用的客车只有一辆 你现在需要计算的是 可以坐满车的接待方案 并且输出有
  • 随笔:使用OpenAI的Embeddings API和Complation API实现客服问答

    去年11月openAI推出了Chat GPT 掀了好大一股浪 前段时间看了一下openAI的API看不看如何通过openAI 的语言处理模型来处理一下客服回复 下面做个笔记记录一下 为什么研究 Open AI 现有的模型没有我们特定场景下的
  • 【Centos】服务管理、解/压缩、磁盘、进程管理相关命令

    文章目录 一 服务管理 1 service 2 chkconfig设置后台服务器的自启配置 3 systemctl 设置后台服务器自启配置 防火墙关闭 4 开关机重启 5 搜索查找类find 6 locate快速定位文件路径 7 其他命令
  • Java语言特点与学习

    Java语言是一款面向对象的一款高级语言是由Sun Microsystems公司 现已被oracle公司收购 由James Gosling和同事们共同研发 并在1995年正式推出 据oracle官方数据指数 目前全球已有上亿的系统是使用Ja
  • io流中用到的设计模式

    总括 适配器模式 装饰者模式 public void testInputStreamReader throws Exception private static final String SEPARATOR File separator F
  • 【Antlr】使用语义判定修改语法分析过程

    文章目录 1 概述 2 识别编程语言中的多种方言 2 案例 2 1 完整案例 1 概述 上一篇文章 Antlr Antlr属性和动作 识别关键字不固定的语句 出自 antlr 权威指南 并且补充 在上一章中 我们学习了如何在语法中嵌入动作
  • 简单了解机器学习(Machine Learning)

    首先 什么是机器学习 笼统来讲 机器学习是通过让机器去学习从而帮助人类做出决定 人类可以说在任何时刻 做任何事情时都在面临着无数的决定 从小的决定 晚饭吃什么 穿哪双鞋 喝什么饮料 到大的决定 专业选什么 工作选什么 定居在哪里 等 我们所
  • 【关于笔记软件的感受、期望,以及初期预案】

    市场 现状 首先看格式 md比较轻量级 支持这个格式的软件也比较广泛 生产力决定生产关系 就目前需要记录的内容和频率数量来看 个人感觉用这个格式承载笔记是最合适的 文字方面 图画多媒体编辑除外 包括在项目中也会用它来做简介 语雀 飞书等等的
  • matlab矩阵分割示例

    下面介绍了使用mat2cell函数把矩阵分割为我们想要的形状 1 先产生一个6x6的随机矩阵作为被分割矩阵 2 比如想把矩阵a分割为4块 也就分为4个3x3的矩阵 方法如下 b mat2cell a 3 3 3 3 运行结果如下 再比如c
  • (一)Android布局时资源文件使用

    一 Android布局时菜单资源文件使用 Android Menu资源的使用 菜单分为三种 OptionsMenu 选项菜单 ContextMenu 上下文菜单 SubMenu 子菜单 OptionsMenu默认情况下是在点击Menu键后出
  • Python 开发桌面应用居然如此简单

    我们都知道 Python 可以用来开发桌面应用 一旦功能开发完成 最后打包的可执行文件体积大 并且使用 Python 开发桌面应用周期相对较长 假如想快速开发一款 PC 端的桌面应用 推荐使用 Aardio Python 搭配的方式进行开发
  • Session(服务端会话跟踪技术)

    开发工具与关键技术 IDEA 撰写时间 2022 10 18 服务端会话跟踪技术 将数据保存到服务端 javaEE 提供HttpSession接口 来实现一次会话的多次请求间数据共享功能 注意 Session 是基于Cookie实现的 Se
  • iOS--Runloop

    Runloop概述 一般来说 一个线程一次只能执行一个任务 执行完成后线程就会退出 就比如之前学OC时使用的命令行程序 执行完程序就结束了 而runloop目的就是使线程在执行完一次代码之后不会结束程序 而是使该线程处于一种休眠的状态 等待
  • 力扣刷题——数组(c++)

    题目 给你一个数组 nums 和一个值 val 你需要 原地 移除所有数值等于 val 的元素 并返回移除后数组的新长度 不要使用额外的数组空间 你必须仅使用 O 1 额外空间并 原地 修改输入数组 元素的顺序可以改变 你不需要考虑数组中超
  • va_list、va_start、va_arg、va_end宏的使用

    当你的函数的参数个数不确定时 就可以使用上述宏进行动态处理 这无疑为你的程序增加了灵活性 Example CString AppendString CString str1 一个连接字符串的函数 参数个数可以动态变化 LPCTSTR str
  • 特斯拉Model 3 Key Card里的黑科技

    特斯拉Model 3给用户提供了三种解锁电动车的姿势 遥控钥匙 可选 需付费购买 手机APP蓝牙解锁 以及 Key Card 钥匙卡片 其中Key Card作为手机蓝牙钥匙的备份方案 以应对手机没电了 忘带了 APP故障 车机蓝牙故障等上不
  • Python实现逻辑回归(LogisticRegression)完整过程

    最近正在做的项目正好利用到了逻辑回归 所以正好系统的学习了下 本篇博文把自己的学习笔记 项目思路及代码都记录下来 它的计算原理很多网站和书籍都有介绍 就不在这班门弄斧了 主要还是记录自己如何实现 一 逻辑回归简介 Logistic Regr
  • matlab中未定义与 ‘cell‘ 类型的输入参数相对应的运算符 ‘+‘ 的解决方案

    在函数文件中写入以下内容 function re fun a b varargin if nargin 2 re a b elseif nargin 3 c varargin 1 re a b c else error wrong end
  • 排序法 C语言常考的十大排序法 数列、字符的排序

    通过对近各大试卷题型分析 总结出 对于数据排序的十大方法 希望对大家有所帮助 方法一 冒泡排序法 升序排序法 方法二 选择排序法 方法三 插入排序法 方法四 希尔排序法 Shell Sort 方法五 归并排序法 方法六 快速排序法 交换排序