c语言各种排序加标注

八大经典排序算法(C语言) 目录 前言 一、冒泡排序 二、快速排序 三、选择排序 四、插入排序 五、归并排序 六、希尔排序 七、堆排序 八、基数排序(正整数) 参考资料   前言         初学编程,记录一下八大经典排序算法,以便后续复习。参考借鉴了很多文章和代码,在本文末尾会进行标注,也在此对各位前辈表示感谢。         本文记录的排序算法有:冒泡排序、快速排序、选择排序、插入排序、... 阅读详情

大佬莫看

1冒泡排序

1.冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地走 访过要排序的数列,一次比较两个元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。

  • 冒泡排序算法的运作

1、比较相邻的元素。如果第一个比第二个大(小),就交换他们两个。
2、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。
3、针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。
4、持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需要比较,则序列最终有序。

  • 算法时间复杂度 o(n2)

  • 稳定性
    冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

#include <stdio.h>//头文件

void dayin(int *a,int len);//打印函数声明
void maopao(int *a,int len);//冒泡排序声明

int main(int argc, char const *argv[])//函数入口
{
   int a[]={1,2,4,3,5,5,7,4,8};
   int len=sizeof(a)/sizeof(int);
   int i;
   maopao(a,len);//冒泡函数调用
   dayin(a,len);//打印函数调用
}

void maopao(int *a,int len)//冒泡函数实现
{
   int i,j,temp;

   for (int i = 0; i < len; i++)
   {
   	for (int j = 0; j < len-i; j++)
   	{
   		if(a[j]>a[j+1])
   		{
   			temp=a[j];
   			a[j]=a[j+1];
   			a[j+1]=temp;
   		}

   	}
   }	
}

void dayin(int *a,int len)//打印函数实现
{
   int i;
   for(i=0;i<len;i++)
   printf("%d",a[i]);
   putchar(10);
}


执行结果
./a.out
123445578


2.选择排序

  • 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。

  • 时间复杂度
    选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。
    比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+…+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。

  • 稳定性
    选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。

void select_sort(int*a,int n)
 
{
 
    register int i,j,min,t;
 
    for(i=0;i<n-1;i++)
 
    {
 
        min=i;//查找最小值
 
        for(j=i+1;j<n;j++)
 
            if(a[min]>a[j])
 
                min=j;//交换
 
        if(min!=i)
 
        {
 
            t=a[min];
 
            a[min]=a[i];
 
            a[i]=t;
 
        }
 
    }
 
}

上边代码的一个模块化,复习一下函数调用
void swap(int *a,int *b) //交換两个整数
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void selection_sort(int arr[], int len) 
{
    int i,j;
 
    for (i = 0 ; i < len - 1 ; i++) 
    {
        int min = i;
        for (j = i + 1; j < len; j++)     //走訪未排序的元素
            if (arr[j] < arr[min])    //找到目前最小值
                min = j;    //紀錄最小值
           swap(&arr[min], &arr[i]);    //做交換
    }
}

3.插入排序

插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到 {\displaystyle O(1)} {\displaystyle O(1)}的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后

挪位,为最新元素提供插入空间。

void insertion_sort(int arr[], int len){
    int i,j,temp;
    for (i=1;i<len;i++){
            temp = arr[i];
            for (j=i;j>0 && arr[j-1]>temp;j--)
                    arr[j] = arr[j-1];
            arr[j] = temp;
    }
}

4 希尔排序

希尔排序
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位

void shell_sort(int arr[], int len) {
    int gap, i, j;
    int temp;
    for (gap = len >> 1; gap > 0; gap = gap >>= 1)
        for (i = gap; i < len; i++) {
            temp = arr[i];
            for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap)
                arr[j + gap] = arr[j];
            arr[j + gap] = temp;
        }
}

5.归并排序

归并排序
把数据分为两段,从两段中逐个选最小的元素移入新数据段的末尾。

可从上到下或从下到上进行。

int min(int x, int y) {
    return x < y ? x : y;
}
void merge_sort(int arr[], int len) {
    int* a = arr;
    int* b = (int*) malloc(len * sizeof(int));
    int seg, start;
    for (seg = 1; seg < len; seg += seg) {
        for (start = 0; start < len; start += seg + seg) {
            int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
            int k = low;
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;
            while (start1 < end1 && start2 < end2)
                b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
            while (start1 < end1)
                b[k++] = a[start1++];
            while (start2 < end2)
                b[k++] = a[start2++];
        }
        int* temp = a;
        a = b;
        b = temp;
    }
    if (a != arr) {
        int i;
        for (i = 0; i < len; i++)
            b[i] = a[i];
        b = a;
    }
    free(b);
}
递归法
void merge_sort_recursive(int arr[], int reg[], int start, int end) {
    if (start >= end)
        return;
    int len = end - start, mid = (len >> 1) + start;
    int start1 = start, end1 = mid;
    int start2 = mid + 1, end2 = end;
    merge_sort_recursive(arr, reg, start1, end1);
    merge_sort_recursive(arr, reg, start2, end2);
    int k = start;
    while (start1 <= end1 && start2 <= end2)
        reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
    while (start1 <= end1)
        reg[k++] = arr[start1++];
    while (start2 <= end2)
        reg[k++] = arr[start2++];
    for (k = start; k <= end; k++)
        arr[k] = reg[k];
}
void merge_sort(int arr[], const int len) {
    int reg[len];
    merge_sort_recursive(arr, reg, 0, len - 1);
}

6 快速排序

在区间中随机挑选一个元素作基准,将小于基准的元素放在基准之前,大于基准的元素放在基准之后,再分别对小数区与大数区进行排序。

过程演示:

迭代法
typedef struct _Range {
    int start, end;
} Range;
Range new_Range(int s, int e) {
    Range r;
    r.start = s;
    r.end = e;
    return r;
}
void swap(int *x, int *y) {
    int t = *x;
    *x = *y;
    *y = t;
}
void quick_sort(int arr[], const int len) {
    if (len <= 0)
        return; // 避免len等於負值時引發段錯誤(Segment Fault)
    // r[]模擬列表,p為數量,r[p++]為push,r[--p]為pop且取得元素
    Range r[len];
    int p = 0;
    r[p++] = new_Range(0, len - 1);
    while (p) {
        Range range = r[--p];
        if (range.start >= range.end)
            continue;
        int mid = arr[(range.start + range.end) / 2]; // 選取中間點為基準點
        int left = range.start, right = range.end;
        do
        {
            while (arr[left] < mid) ++left;   // 檢測基準點左側是否符合要求
            while (arr[right] > mid) --right; //檢測基準點右側是否符合要求
 
            if (left <= right)
            {
                swap(&arr[left],&arr[right]);
                left++;right--;               // 移動指針以繼續
            }
        } while (left <= right);
 
        if (range.start < right) r[p++] = new_Range(range.start, right);
        if (range.end > left) r[p++] = new_Range(left, range.end);
    }
}
递归法
void swap(int *x, int *y) {
    int t = *x;
    *x = *y;
    *y = t;
}
void quick_sort_recursive(int arr[], int start, int end) {
    if (start >= end)
        return;
    int mid = arr[end];
    int left = start, right = end - 1;
    while (left < right) {
        while (arr[left] < mid && left < right)
            left++;
        while (arr[right] >= mid && left < right)
            right--;
        swap(&arr[left], &arr[right]);
    }
    if (arr[left] >= arr[end])
        swap(&arr[left], &arr[end]);
    else
        left++;
    if (left)
        quick_sort_recursive(arr, start, left - 1);
    quick_sort_recursive(arr, left + 1, end);
}
void quick_sort(int arr[], int len) {
    quick_sort_recursive(arr, 0, len - 1);
}
数据结构与算法C语言版 学生成绩统计 作者:杨 版权声明: 本文为博主原创文章,转载请附上源文链接! 本文链接:https://my.oschina.net/yangmufa/blog/3096426 首先创建一个线性表用来存储学生成绩,每个学生的成绩作为一个数据元素对应标注的一行。 定义线性表的结构体类型... 阅读详情

相关推荐

Revit_MEP管道自动标注及优化布置算法的研究

Revit_MEP管道自动标注及优化布置算法的研究 (1)深入研究 BIM 本质及核心,发掘出 Revit MEP 中管道的各种排布特点。 分类管道的各种排布情况,研究其特性,建立了一种基于三角几何关系中垂线定 理的方法,有效解决了复杂的多变径、多分支批量自动标注问题。 (2)研究 Revit 软件建模方法,根据 Revit MEP 中管道的排布特性构建相应 的框架,利用本文设计的管道批量自动标注算法实现管道自动标注功能插件的设 计。 (3)以管道自动标注为基础,借鉴前人在其他领域中标注优化布置算法的经 验,分析 Revit MEP 中各个构件的特征属性,将其分成线性型特征构件与节点型 特征构件,进而设计了一种基于 BIM 技术的标注优化布置算法。

自动标注和优化布置——资料搜集

摸鱼产物——自动标注胡扯。

qq_36699935的博客 199

MTK平台TP驱动设备树与GPIO配置实战解析

本文详细解析了MTK平台TP驱动开发中的设备树与GPIO配置实战。通过DCT工具配置GPIO引脚,结合设备树节点定义触摸参数,并分享驱动移植、编译调试技巧及常见问题解决方案,帮助开发者快速掌握MTK触摸驱动开发核心。

ice55的博客 234

算法--排序算法总结

近期重新看了排序算法,在此做一个总结。在写算法之前首先要写一个生成数组的函数。这个函数生成规定范围内的n个不重复的随机数,下面介绍的所有的算法都用这个函数生成数组。 #ifndef CREATEDATA_H #define CREATEDATA_H #include #include //生成不重复的随机整数,n数组长度,min-max生成随机数的范围 int CreateData(i

428

Java8动态生成SFunction:基于字段名的Lambda表达式实践

本文深入探讨了在Java8中如何基于字段名动态生成SFunction,以解决MyBatis Plus的LambdaQueryWrapper在动态查询场景下的局限性。通过核心原理LambdaMetafactory的解析和手把手的代码实现,展示了如何将字符串字段名转换为类型安全的Lambda表达式,从而实现真正动态、类型安全的查询条件构建与通用数据处理,显著提升代码的灵活性与安全性。

sss66的博客 953

避坑指南:雅特力AT32F403A在Keil5中的V2库配置常见问题解析

本文详细解析了国产MCU雅特力AT32F403A在Keil5中配置V2库的常见问题,包括工程创建、库文件配置、编译错误和外设设置等关键环节。针对项目文件夹结构混乱、芯片型号选择错误、头文件路径设置不当等典型问题提供实用解决方案,帮助开发者高效避坑,提升开发效率。

weixin_30335575的博客 376

C 语言排序算法

帮助你快速理解排序算法

qq_52184758的博客 1443

《解锁GCC版本选择的奥秘:从入门到精通》

GCC 版本的选择是一项复杂而关键的决策,犹如一场精心策划的战略布局,贯穿于软件开发的整个生命周期。从项目需求与兼容性的深度考量,到性能与稳定性的权衡抉择,再到硬件与系统适配的精准对接,每一个环节都紧密相连,相互影响。在游戏开发行业,对性能的极致追求促使开发者青睐较新的 GCC 版本,以实现更流畅的游戏体验和更震撼的视觉效果;科学计算领域则依赖于 GCC 版本对复杂数学运算的高效优化,以应对大规模数据处理的挑战;嵌入式开发行业因硬件资源的限制和对稳定性的严苛要求,通常选择经过长期验证的稳定版本;

zheng_ruiguo的专栏 1418

常见排序算法

直接插入排序(Insertion sort) 算法思想:从第二个数开始,和前面每一个数进行比较,若前面的数更小,则将前面的数后移,然后将该数插入空位,直到该数比前一个数更大为止。假设共有n个数,则一共需要比较n-1次 C语言代码实现 //自定义的函数Insertion_sort解决插入排序问题 void Insertion_sort(int a[],int n) { int i,j; //自定义循环变量 int temp; //

u011585791的博客 208

STM32驱动MG996R舵机的PWM控制与闭环原理

舵机是一种典型的模拟闭环伺服系统,其核心是通过电位器反馈实现角度位置的自动校正。工作原理基于负反馈控制:目标PWM脉宽决定期望角度,电位器输出实时反馈实际角度,控制电路计算偏差并驱动电机消除误差。该机制赋予舵机强带载能力与抗干扰性,是机器人、云台、智能执行器等场景的关键执行单元。在嵌入式开发中,STM32通过定时器生成标准20ms周期、0.5–2.5ms脉宽的PWM信号,需严格遵循电气规范,并解决PA15引脚SWJ复用冲突、定时器重映射及CCR精度计算等关键问题。本文深入解析MG996R舵机控制全流程,涵盖

weixin_42600407的博客 562

OMAPL138使用UPP读写测试

UPP测试代码 #include "hw_types.h" // 宏命令 #include "hw_syscfg0_OMAPL138.h" // 系统配置模块寄存器 #include "soc_OMAPL138.h" // DSP C6748 外设寄存器 #include "psc.h" // 电源与睡眠控制宏及设备抽象层函数声明 #include "interrupt.h" // DSP C6748 中断相关应用程序接...

wangjie36的博客 1193

【初学者入门C语言】之算法篇(冒泡排序和选择排序)

通俗易懂的解析冒泡排序和选择排序(建议初学者收藏)

m0_67388084的博客 2597

开关电源中的高频振荡噪声及其抑制方法

在开关电源的工作过程中,随着开关管的开关动作,电流和电压波形会出现剧烈的波动,尤其是在开关管切换的瞬间,往往会导致较强的过冲现象。开关电源中的高频振荡噪声是导致电磁兼容问题的主要源头之一,尤其是MOS管的通断和整流二极管的反向恢复过程中,会产生较强的高频振荡噪声。通过合理调节R和C的值,可以大大缓解高频振荡带来的EMC问题,从而有效提升电源的电磁兼容性。整流二极管反向恢复时的振荡会导致高频噪声产生,这些高频噪声源可被传导到电源的输出端,甚至可能通过电源的共地路径扩散到其他电路,影响系统的稳定性和可靠性。

硬核科技 1531

C语言排序问题

先前对C语言有一定的的入门知识,但是由于

c03s315的专栏 1104

6、探索音乐结构中的统一性:贝多芬《英雄交响曲》第一乐章的深度剖析

本文深入剖析了贝多芬《英雄交响曲》第一乐章的音乐结构,探讨其统一性的来源及表现形式。通过主题与动机、和声与调性、旋律与节奏、织体与动态等多方面的分析,揭示了这部作品在技术层面和情感表达上的卓越成就。

b9c0d的博客 518

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C语言练习之姓名排序

土木,爽!

dyudbegdu的博客 1257

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C语言实现快速排序(附带源码)

C语言实现快速排序(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 1380

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

c语言排序成绩没有输出来,快速排序(c语言) 输出结果根本没有排序!~

满意答案0502345ESD2014.01.12采纳率:50%等级:12已帮助:9025人错误的地方我用注释标注出来.#include"stdio.h"#include"stdlib.h"typedef struct{int key;char info;}RedType;typedef struct{RedType r[20];int length;}Sqlist;void Createl...

weixin_29027305的博客 308

吉林大学计算机系高级语言程序设计(C语言)期末题目及解答(下)

因为正在准备考研复试,所以计划把吉大期末的C语言题目重新刷一遍(上机),做为笔记放在这里,有需要的朋友请自提~

Cambridge26的博客 3973

C语言对链表的排序问题

C语言中,若想直接对链表进行排序或许有些复杂,而且一个节点中可能有多个键值,如果要对链表实现多个键值的排序则更加复杂。 考虑到这个问题的复杂性,我想到了之前学过的指针数组,令数组存储一系列指针,这些指针分别指向链表的每一个节点,当需要排序时,只需将这些指针进行排序即可,这样实现的速度快,且能减少代码量。 具体实现实例请参考我的另一篇文章: https://blog.youkuaiyun.com/qq_45853731/article/details/107889388 ...

qq_45853731的博客 820

二叉排序树(BST)删除结点算法详解之C语言版

在二叉排序树上删除某个结点,后的二叉树仍旧是一棵二叉排序树。 删除结点主要包含了以下四种情形: 1) 删除叶子结点 2) 删除只有左子树的结点 3) 删除只有右子树的结点 4) 删除左右子树均不空的结点** 针对第一种情形,直接删除树叶结点即可; 针对第二种情形,待删除结点的 左子树 树根替代待删除的结点即可; 针对第三种情形,待删除结点的 右子树 树根替代待删除的结点即可; 针对第四种情形,需要找到待删除结点的左子树最右侧的结点s,用其代替删除的结点即可。

sunnyoldboy博客 8545

复古 C 语言插入排序代码修复与深度解析 —— 41 号代码

对旧的C语言代码进行修改恢复其功能

heqishengc的博客 764

试题 基础练习 数列排序(快速排序算法)(C语言)(官网测试通过)

问题描述   给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200 输入格式   第一行为一个整数n。   第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000。 输出格式   输出一行,按从小到大的顺序输出排序后的数列。 样例输入 5 8 3 6 4 9 样例输出 3 4 6 8 9 老规矩先上代码。 # include <stdio.h> void kuaipai(int *,int ,int ); void j...

菜鸟的博客 2208

C语言_选择排序

选择排序是将待排序的第一个元素与其他另外的元素进行比较选出(最大(就是升序)或最小的(就是降序))与第一个排序的元素进行交换#include<stdio.h> int main() { int i; int j; int a[10]={9,8,7,6,5,4,3,2,1,10}; int k;//标注下标 int temp; //排序是升序排序

Sunflower_grh的博客 617

基于C语言的邮票组合问题解决方案及调试实践

本次课程报告实践围绕古老C语言代码的修复、解析与管理展开,全程遵循课程要求,从选题到最终提交经历了编译调试、功能理解、环境配置、代码托管等多个关键环节。通过本次实践,我不仅成功解决了邮票组合的算法问题,更在技术能力和思维方式上获得了显著提升:在技术层面,熟练掌握了Dev-C++和VSCode两款编译器的使用,深入理解了C语言标准语法与非标准语法的差异,学会了通过搜索引擎、AI工具和技术博客排查解决代码错误;

2501_93994188的博客 2648

数据结构(c语言)--排序算法之插入排序(直接插入排序、希尔排序)

王道数据结构(c语言)--排序算法之插入排序(直接插入排序、希尔排序)

weixin_46625488的博客 601
上一篇: 什么是死锁,死锁的原因,如何避免
下一篇: 指针数组和数组指针解析
专业的坑
博客等级 码龄8年 6粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值