• 【8】算法排序 (快速排序)


    参考:https://wiki.jikexueyuan.com/project/easy-learn-algorithm/fast-sort.html

    基本思想:

      通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 

    方法:

      在冒泡排序的基础上采用分治和递归的思想;

    步骤:

    • 选一个temp元素(随意选择)
    • 小于tmp放左边, 大于tmp放右边
    • 对左半边,重复进行以上两步骤
    • 对右半边,重复进行以上两步骤
    • 递归直到半区内只有一个元素的时候返回

    时间复杂度:

      

    解析:

      int  *  a  = {10, 8, 5, 21, 4 ,9 , 6};
    
      temp = 6;   // 将temp设置为最右边元素
    
      i = 10;     // i为最左边的元素
    
      j = 9;       // j为最右边的元素 不包括temp
    
      j - - 大于temp的数分为一组, i + + 小于temp的数分为一组

    第一轮:
    i++ 10 不小于 6 i=0
    j-- 9 大于 6 j-- 4 不大于 6 j=5

    10 < 4? 互换位置
    4,8,5,21, 10, 9, 6
    4 < 6? 不换位置
    第一轮结果:4,8,5,21, 10, 9, 6

    
    


    第二轮:
    i++ 8 不小于 6 i=1
    j-- 21 大于 6 j-- 5 不大于 6 j=2

    8 > 5 ? 互换位置
    4,5,8,21, 10, 9, 6
    8 < 6 ? 互换位置
    第二轮结果: 4,5,6,21, 10, 9, 8

     完整代码

                               
    #include <stdio.h>
    
    void PrintSort(int * a, int n)
    {
            int i;
            for (i=0; i<n; i++) {
                    printf("%d  ", a[i]);
            }
            printf("
    
    ");
    }
    
    void swap(int * a, int *b )
    {
            int t = *a;
            *a = *b;
            *b = t;
    }
    
    int partition(int * a, int low, int high)
    {
            int i = low - 1; // low - 1 因为后面是(++i), 若不减一则从下标1开遍历,漏了一个数
            int j = high;
            int temp = a[high];
            while(1) {
                    while(a[++i] < temp);
                    while(a[--j] > temp);
                    if (i<j) {
                            swap(&a[i], &a[j]);
                    } else {
                            break;
                    }
            }
         // 每一轮结束前,的最后一步,将mid跟temp比较
            swap(&a[i], &a[high]);
            return i;
    }
    
    // 写法一
    void QuickSort1(int * a, int low, int high)
    {
            if (low < high) {
                    int mid = partition(a, low, high);
                    QuickSort1(a, low, mid-1);
                    QuickSort1(a, mid+1, high);
            }
    }
    
    // 写法二
    void QuickSort2(int * a, int low, int high)
    {
            if (low >= high) return;
            int i = low;
            int j = high;
            int temp = a[low];
            while(i<j) {
                    while(i<j && temp <= a[j]) {
                            j--;
                    }
                    a[i] = a[j];
                    while(i<j && temp >= a[i]) {
                            i++;
                    }
                    a[j] = a[i];
            }
    
            a[i] = temp;
            QuickSort2(a, low, i-1);
            QuickSort2(a, i+1, high);
    }
    
    int main()
    {
            int a[11] = {33, 40, 1, 14, 7, 35, 27, 9, 55, 80, 61};
            QuickSort1(a, 0, 10); // 从下标0开始
            printf("方法一:
    ");
            PrintSort(a, 11);
    
            int b[11] = {33, 40, 1, 14, 7, 35, 27, 9, 55, 80, 61};
            printf("方法二:
    ");
            QuickSort2(b, 0, 10);
            PrintSort(b, 11);
    }

    做一个优秀的程序媛
  • 相关阅读:
    在 git 上 push 之后的代码如何撤回
    Git 如何暂存代码
    使用 Maven 聚合⼯程创建微服务
    使用 K8spacket 和 Grafana 对 K8S 的 TCP 数据包流量可视化
    Ceph 存储的那点事儿 — Trim/Discard
    7 张图解 CrashLoopBackOff,如何发现问题并解决它?
    Kubernetes 和 容器的退出码完整指南
    刚刚 Kubernetes 1.25 正式发布,包括这些重大变化
    在 MacOS 上通过 Lima 使用 Docker
    Consul API Gateway 0.4 已正式发布,包括这些新功能
  • 原文地址:https://www.cnblogs.com/oytt/p/13578361.html
Copyright © 2020-2023  润新知