zoukankan      html  css  js  c++  java
  • 八大排序

     一:排序分类

    二、算法实现(内部排序)

    1、插入排序之直接插入排序

    排序步骤:

    ①从第一个元素开始,该元素可以认为已经被排序
    ②取出下一个元素,在已经排序的元素序列中从后向前扫描
    ③如果该元素小于前面的元素(已排序),则依次与前面元素进行比较如果小于则交换,直到找到大于该元素的就则停止;
    ④如果该元素大于前面的元素(已排序),则重复步骤2
    重复步骤2~4 直到所有元素都排好序

    例:3 4 7 1 5 2 6 9(排成递增序列)

    排序过程:i = 1:3 4 7 1 5 2 6 9 (3和4比)

         i = 2:3 4 7 1 5 2 6 9 (4和7比)

           i = 3:①3 4 1 7  5 2 6 9(1和7比)

            ②3 1 4 7 5 2 6 9(1 和4比)

            ③1 3 4 7 5 2 6 9(1和3比)

        ......

        i = 8:1 2 3 4 5 6 7 9

    使用直接插入排序的优点是稳定,快速,缺点是:比较次数不一定,比较次数越多,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。平均时间复杂度O(n^2),适合于量级小于千的排序。

    清单1:

    int StraightInsertSort(int s[],int n)
    {
      int i,j;
      int temp;
      for(i = 1;i<n;i++)
      {
        for(j = i; j > 0;j--)
        {
          if(s[j] < s[j-1])
          {
            temp = s[j];
            s[j] = s[j-1];
            s[j-1] = temp;
          }
          else
          break;
        }
      }
    }

    2、插入排序之希尔排序

    原理:已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以此类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。

    优点:快,数据移动少

    缺点:d值不确定,取什么值看经验

    希尔排序的时间复杂度为 O(N*(logN)2),适合于中等规模排序

    清单2:

    int sheelsort(int a[],int n)
    {
      int k = n / 2;//k是增量
      while (k > 0)
      {
        for (int i = k; i < n; i++)
        {
          int t = a[i];
          int j = i - k;
          while (j >= 0 && t < a[j])
          {
            a[j + k] = a[j];
            j = j - k;
          }
          a[j + k] = t;
         }
         k /= 2;
      }
    }

    3.选择排序之简单选择排序

    ①从左至右遍历,找到最小(大)的元素,然后与第一个元素交换。
    ②从剩余未排序元素中继续寻找最小(大)元素,然后与第二个元素进行交换。
    ③以此类推,直到所有元素均排序完毕。

    有序区,无序区

    优点:移动数据的次数已知(n-1次)。
    缺点:比较次数多,不稳定
    例:3 4 7 1 5 2 6 9(排成递增序列)
    第一趟排序:     4 7 3 5 2 6 9
         有序区    无序区
    第二趟排序:1 2     7 3 5 4 6 9
                   有序区    无序区
    第三趟排序:1 2 3  7 5 4 6 9
         有序区   无序区
    。。。。。。
          1 2 3 4 5 6 7 9
    清单3:

    int selectionsort(int a[],int n)
    {
      int i,j,temp;
      //一趟一趟的找
      for(i = 0; i < n;i++)
      {
        int min = i;
        //找最小值,记录位置
        for(j = i+1; j < n; j++)
        {
          if(a[min] > a[j])
            min = j;
        }
        //找到后交换值
        temp = a[min];
        a[min] = a[i];
        a[i] = temp;
      }
    }

    4.堆排序 

    示例:

    5、冒泡排序

    一组数据,两两比较,大的放后面,小的放前面,就像冒泡一样,越大的泡会冒到最上面,一趟一趟比较,直到所有数据从小到大依次排列。

    算法分析:

    ①相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

    ②平均时间复杂度o(n^2)

    清单5:

    int Bubblesort(int a[],int n)
    {
      int i,j,min;
      for(j = 1; j < n; j++)    //控制排序的执行次数
      {
        for(i = 0; i < n-j; i++)   //控制在一次排序中相邻记录的比较和交换
        {
          if(a[i] > a[i+1])  //如果前面元素大于后面元素则交换
          {
            min = a[i+1];
            a[i+1] = a[i];
            a[i] = min;
          }
        }
      }
    }

    6、快速排序

    快速排序又叫分区交换排序,是目前已知的平均速度最快的一种排序方法。基本思想:从待排序的n个记录中任意选取一个记录Ri(通常选取序列中的第一个记录)做标准,调整序列中各个记录的位置,使排在Ri前面的记录的关键字都小于Ri.key,排在Ri后面的记录的关键字都大于等于Ri.key,我们把这样的一个过程称作一次快速排序。在第一次快速排序过程中,确定了所选取的记录Ri最终在序列中的排列位置,同时也把剩余的记录分成了两个子序列。对两个子序列分别进行快速排序,又确定了两个记录在序列中应处的位置,并将剩余记录分成了四个子序列,如此重复下去,当各个子序列的长度为一时,全部记录排序完毕。

    算法分析:

    ①是一种不稳定的排序方法

    ②递归形式的快速排序法需要栈空间暂存数据,其空间复杂度为O(n)

    ③时间复杂度是o(nlgn)

    清单6:

    int quicksort(int a[],int low,int high)
    {
      int i,j,temp;
      i = low;
      j = high;
      temp = a[i];
      while(i < j)
      {
        //从右向左找第一个比temp小的元素
        while(i < j && temp <= a[j])  //如果满足此条件,即temp的值比a[j]小
          j--;                 //则j向左移动
        if(i < j)                //当不满足while循环的条件,即找到了一个比temp小的数,只要i<j,
        {
          a[i++] = a[j];        //将找到的小的数a[j]的值赋给a[i],i = i+1
        }
        //同理从左向右找第一个比temp大的元素
        while(i < j && temp >= a[i])  //如果满足此条件,即temp的值比a[i]大
          i++;          //则i向右移动
        if(i < j)                  //当不满足while循环的条件,即找到了一个比temp大的数,只要i<j,
        {
          a[j--] = a[i];        //将找到的大的数a[i]的值赋给a[j],j = j-1
        }
        a[i] = temp;
        //使用递归实现子序列的排序
        if(low < i)
        {
          quicksort(a,low,i-1);
        }
        if(i < high)
        {
          quicksort(a,j+1,high);
        }
      }

    }

    7、归并排序

    8、基数排序

    总结:

    待续~~

  • 相关阅读:
    LeetCode 79. 单词搜索
    LeetCode 1143. 最长公共子序列
    LeetCode 55. 跳跃游戏
    LeetCode 48. 旋转图像
    LeetCode 93. 复原 IP 地址
    LeetCode 456. 132模式
    LeetCode 341. 扁平化嵌套列表迭代器
    LeetCode 73. 矩阵置零
    LeetCode 47. 全排列 II
    LeetCode 46. 全排列
  • 原文地址:https://www.cnblogs.com/wqblogs918/p/7591125.html
Copyright © 2011-2022 走看看