美文网首页
算法学习之简单排序

算法学习之简单排序

作者: 聪明叉 | 来源:发表于2016-04-23 18:47 被阅读40次

简单排序

简单排序有三种, 冒泡排序,选择排序,插入排序

冒泡排序

冒泡排序是一种易于实现的排序算法, 以升序为例:

有n个数, 需要比较n-1轮, 每轮比较数组中相邻的两个数, 前者大就交换两数.

第一轮时, 最大的数就会如冒泡般移向队尾, 下一轮比较就可以少比较一个数.

//冒泡排序
void bubbleSort(int arr[], int n){
    for (int i = 0; i < n-1 ; i++ ) {
        for (int j = 1; j < n - i; j++) {
            if (arr[j - 1] > arr[j]) {
                swap(&arr[j-1], &arr[j]);
            }
        }
    }
}

因为用的是C语言, 遇到了java中完全遇不到的两个bug.

第一点是交换值, 必须要传地址才有卵用, 否则毫无卵用

// 交换函数, 必须传递引用才能交换成功
// 传值只是将实参复制给了形参一份, 在函数内如何改变形参与实参无关
// 传递引用, &arr[i], 取地址, a = &arr[i], *a = *(&arr[i]) = arr[i]
// 因此改变的就是实参的值
void swap(int *a, int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

另一点是获取数组长度.

按照道理, 用运算符sizeof可以计算出数组的容量(字节数),在除以单个元素的容量就能得到数组的长度了.

(sizeof(array) / sizeof(array[0]));

结果我真的是naive. 当我想打印数组时, 搞了个函数

void printfArray(int arr[]){
    int len = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < len; i++) {
        printf("%d, ", arr[i]);
    }
}

怎么打都只能打出两个数字, 百思不得其解啊尼玛

在C/C++中, 数组在作为参数传递时, 会退化为同类型的指针, 并没有办法知道指针所指的内存容量,除非在申请内存时记住它。

无论数组长度为多少, 以int数组为例, sizeof(a)始终等于sizeof(int *), 所以函数中传递只能把传数组个数传过去

void printfArray(int arr[], int len){
    for (int i = 0; i < len; i++) {
        printf("%d, ", arr[i]);
    }
}

选择排序

选择排序, 以升序为例:

第一轮比较, 从arr[0]开始依次比较, 找出最小的数的下标, 记录下来, 将arr[0]与最小值交换.

第二轮从arr[1]开始依次比较, 找出最小的数的下标, 记录下来, 将arr[1]与最小值交换.

...

直到交换完成

void selectSort(int arr[], int n){
    for (int i = 0; i < n; i++) {
        int min = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[min]) {
                min = j;
            }
        }
        swap(&arr[i], &arr[min]);
    }
}

插入排序

插入排序的思路是,将单个数字插入有序集合. 大致思想是, 先将第一个数看做有序区, 后面的数依次插入, 形成新的有序区, 直到排序完成.

以升序为例, 比如这样一个数组 {4, 2, 7, 3}

第一轮, 第一个数字4看做有序区, 后面的数字插入. 开始比较2和4,发现2更小,继续向前查找,没有数字,因此将2插入4的位置,4向后移。这时数组变成了{2, 4, 7, 3}

第二次,遍历到7,向前比较, 有序

第三次,3和7比较,7更大,3应该插入前面。继续向前比较,比较到2才找到了合适的位置。将3插入4的位置,4、7向后移动一位。

下面开始撸代码

// 直接插入排序
void insertSort(int arr[], int n){
    for (int i = 0; i < n; i++) {
        // 后面的数比前面的数大时, 准备插入
        if (arr[i] > arr[i+1]) {
            // 存储待插入的数
            int temp = arr[i+1];
            int j;
            // 向前查找合适的插入位置
            for (j = i; j>=0 && temp < arr[j]; j--) {
                // 逐步后移数组
                arr[j+1] = arr[j];
            }
            // 交换
            arr[j+1] = temp;
        }
    }
}

相关文章

  • 算法理解之排序-冒泡排序

    算法理解之排序-冒泡排序 冒泡排序是一种简单的排序算法, 算法依次走访未排序的元素, 然后将相邻元素依次两两比较,...

  • 常见排序算法之冒泡排序

    常见排序算法之冒泡排序 冒泡排序(Bubble Sort),是一种较简单的排序算法。它重复地走访过要排序的元素列,...

  • 经典排序算法总结

    经典排序算法集锦 冒泡法 排序算法入门之冒泡排序 排序算法入门之冒泡排序优化

  • 排序基础(一)

    排序算法 O(n2)的排序算法 为什么要学习O(n2)的排序算法? 基础 编码简单,易于实现,是一些简单场景的首选...

  • 算法理解之排序-选择排序

    算法理解之排序-选择排序 选择排序是一种简单直观的排序算法, 以当前点为锚点, 向后依次进行比较所有未排序元素, ...

  • 『算法』之 初级排序算法总结

    本篇文章同时收录在我的个人博客:『算法』之 初级排序算法总结 选择排序 一种最简单的排序算法:首先,找到数组中最小...

  • 3.1-选择排序-简单选择排序

    参考链接 选择排序:简单选择排序(Simple Selection Sort) 白话经典算法系列之四 直接选择排序...

  • 《算法4》2.1 - 选择排序算法(Selection Sort

    选择排序算法(Selection Sort)是排序算法的一种初级算法。虽然比较简单,但是基础,理解了有助于后面学习...

  • 冒泡排序

    人们开始学习排序算法时,通常都先学冒泡算法,因为它在所有排序算法中最简单。然而,从运行时间的角度来看,冒泡排序是最...

  • 算法与数据结构(二):排序篇-O(n^2)算法:选择 &

    排序基础 O(n^2)的算法虽然简单,但也实用!让我们从最简单的基础排序算法开始,打开我们的算法大门! 排序算法 ...

网友评论

      本文标题:算法学习之简单排序

      本文链接:https://www.haomeiwen.com/subject/ljtfrttx.html