七大排序算法 - 冒泡、简单选择、直接插入、希尔、堆、归并、快速

排序的相关概念

排序的分类

  • 根据在排序过程中带排序的记录是否全部被放置在内存中,排序分为:

    • 内排序

    • 外排序

1.内排序

内排序是在排序整个过程中,带排序的所有记录全部放置在内存中

影响内排序的主要因素

  • 时间性能。

    • (主要受比较移动两种操作的影响)

  • 辅助空间。

  • 算法的复杂性。

内排序的分类

根据排序过程中借助的主要操作,内排序分为:

  • 插入排序

  • 交换排序

  • 选择排序

  • 归并排序

2.外排序

外排序是由于排序的记录个数太多,不能同时放置在内存中,整个排序过程需要在内外存之间多次交换数据才能进行

按照算法的复杂度分类

  • 简单算法:

    • 冒泡排序、简单选择排序、直接插入排序。

  • 复杂排序:

    • 希尔排序、堆排序、归并排序、快速排序。

 


 

一、冒泡排序算法

因为在冒泡排序中要用到顺序表结构数组两元素的交换,先把这些写成函数


#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 100
#define TRUE 1
#define FALSE 0

typedef struct {
    
    int r[MAXSIZE + 1];
    int length;
}SqList;


void swap(SqList *L, int i, int j){
    int temp = L->r[i];
    L->r[i] = L->r[j];
    L->r[j] = temp;
}

1.1 冒泡排序的初级版实现

冒泡排序(Bubble Sort)是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止

void BubblSort0(SqList *L){

    int i,j;
    
    for (i = 1; i < L->length; i++)
        for (j = i+1; j <= L->length; j++)
            if (L->r[i] > L->r[j])
                swap(L, i, j);
}

对于这段代码,是最简单的冒泡,其实就是最简单的交换排序而已。它的思路就是让每一个关键字,都和它后面的每一个关键字比较,如果大则交换,这样第一位置的关键字在第一次循环后一定变成最小值

假设我们待排序的关键字序列是{9,1,5,8,3,7,4,6,2}

  • i = 1时,9与1交换后,在第一位置的1与后面的关键字比较都小,因此它就只最小值。

  • i = 2时,第二位置先后由9换成5,换成3,换成2,完成了第二小的数字交换。

  • 后面数字依次比较和交换,得到最终结果。

 

1.2 冒泡排序的实现

对于上面的算法,代码虽然简单易懂,但是效率非常低。可以改进成接下来的代码


void BubbleSort(SqList *L){
    int i,j;
    for (i = 1; i < L->length; i++)
        for (j = L->length - 1; j >= i; j--)
            if (L->r[j] > L->r[j+1])
                swap(L, j, j+1);
}

代码解释

假设我们待排序的关键字序列是{9,1,5,8,3,7,4,6,2}

  • i = 1时,变量j由8反向循环到1,逐个比较,将较小值交换到前面,直到最后找到最小值放置在了第1的位置。

  • i = 1、 j = 8时,6 > 2 ,因此交换了它们的位置,j = 7时,4 > 2, 所以交换......直到j = 2时,因为 1 < 2, 所以不交换。

  • j = 1 时,9 > 1,交换,最终得到最小值1放置第一的位置。

  • 在不断循环的过程中,除了将关键字1放到第一的位置,还将关键字2从第九位置提到了第三的位置,显然比前面的算法有进步。

  • i = 2时,变量j由8反向循环到2,逐个比较,在将关键字2交换到第二位置的同时,也将关键字4和3有所提升

     

1.3 冒泡排序的优化

  • 在排序的过程中,增加一个标记变量flag来记录位置是否发生了变化

  • 如果没有发生交换,说明数组已经有序了。

  • 
    void BubbleSort1(SqList *L){
        int i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值