美文网首页
经典排序算法一(冒泡排序、快速排序)

经典排序算法一(冒泡排序、快速排序)

作者: 头像是我老婆 | 来源:发表于2017-09-01 10:28 被阅读0次

一张经典算法图镇楼。


十大经典排序算法

正文

常用术语说明

稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;

内排序:所有排序操作都在内存中完成;
外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;

时间复杂度: 一个算法执行所耗费的时间。
空间复杂度: 运行完一个程序所需内存的大小。

排序分类


对于我这种只是想简单了解一下排序算法的人来说,这6种(冒泡排序、快速排序、简单选择排序、直接插入排序、堆排序和希尔排序)算法的学习就已经足够了。

算法介绍(全部以C语言的形式介绍)

int array[] = {6 ,1 ,2 ,7 ,9 ,3 ,4 ,5 ,10 ,8};
int num = sizeof(array)/sizeof(int);
  1. 冒泡排序(Bubble Sort)
    人生中接触的第一种排序方法。
  • 算法描述
    通过交换使相邻的两个数变成小数在前大数在后,这样每次遍历后,最大的数就“沉”到最后面了。重复N次即可以使数组有序。
  • 算法实现
  for (int i = 0; i < num - 1; i++) {
      for (int j = 0; j < num - 1 - i; j++) {
            if (array[j] > array[j + 1]) {
            int tmp = array[j];
            array[j] = array[j + 1];
            array[j + 1] = tmp;
          }
      }
  }
  1. 快速排序(Quick Sort)
  • 算法描述

    1.在待排序的元素任取一个元素作为基准(通常选第一个元素,但最的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
    
    2.将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
    
    3.对左右两个分区重复以上步骤直到所有元素都是有序的。
    
    所以我是把快速排序联想成东拆西补或西拆东补,一边拆一边补,直到所有元素达到有序状态。
    
  • 算法实现
  void sort(int *a,int left,int right) {
      if (left >= right) {
          return;
      }
    // 由于已经将a[0]中的数保存到key中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。
    // 从j开始向前找一个比X小或等于X的数。当j=8,符合条件,将a[8]挖出再填到上一个坑a[0]中。a[0]=a[8]; i++;  这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于X的数,当i=3,符合条件,将a[3]挖出再填到上一个坑中a[8]=a[3]; j--;
   
      int i = left;
      int j = right;
      int key = a[i]; //a[i]就是第一个坑
    
      while (i < j) {
          // 从右向左找小于x的数来填s[i]
          while (i < j && key <= a[j]) {
              j--;
          }
          a[i] = a[j];
          while (i < j && key >= a[i]) {
              i++;
          }
          a[j] = a[i];
      }
      a[i] = key;
      sort(a, left, i-1);
      sort(a, i+1, right);
  }

还有一种比较个性理解的版本:一次循环先交换大小的,最后才和基数的交换。

在博客坐在马桶上看算法:快速排序看到的,评论区各种吵架,说这不是快排。感觉思路是一样的。代码如下

  void sort1(int *a,int left,int right) {
      if (left >= right) {
          return;
      }
      int i = left;
      int j = right;
      int key = a[i];
    
      while (i != j) {
          //顺序很重要,要先从右边开始找
          while (i < j && key <= a[j]) {
              j--;
          }
          //再找左边的
          while (i < j && key >= a[i]) {
              i++;
          }
          //交换两个数在数组中的位置
          if(i < j){
              int t=a[i];
              a[i]=a[j];
              a[j]=t;
          }
      }
      //最终将基准数归位
      a[left]=a[i];
      a[i]=key;
      sort1(a, left, i-1);
      sort1(a, i+1, right);
}

经典排序算法二(选择排序、堆排序)
经典排序算法三(插入排序、希尔排序)

相关文章

网友评论

      本文标题:经典排序算法一(冒泡排序、快速排序)

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