zoukankan      html  css  js  c++  java
  • 数据结构-快速排序

    1、快速排序(最好的内排序)

    1)在待排序的元素任取一个元素作为基准(通常选第一个元素,但最好的选择方法是从待排序元素中随机选取一个作为基准),称为基准元素;
    2)将待排序的元素进行分区,比基准元素大的元素放在它的右边,比其小的放在它的左边;
    3)对左右两个分区重复以上步骤直到所有元素都是有序的。

    #include <stdio.h>
    #include <stdlib.h>
    
    void swap(int k[], int low, int high)
    {
        int temp = k[low];
        k[low] = k[high];
        k[high] = temp;
    }
    
    //交换顺序表中子表顺序,返回枢纽所在的位置,此时在枢纽之前(不大于)后(不小于)
    int Partition(int k[], int low, int high)
    {
        int pivotkey;
        pivotkey = k[low]; //枢纽选取为第一个元素
        while (low < high)
        {
            while (low < high && k[high] >= pivotkey)//将右侧比枢纽小的值,调整至低端
                high--;
            swap(k, low, high);
            while (low < high && k[low] <= pivotkey)//将左侧比枢纽大的值,调整至高端
                low++;
            swap(k, low, high);
        }
        return low;//此时low=high,返回枢纽所在位置
    }
    
    void QuickSort(int k[], int low, int high)
    {
        int pivot;
        if (low < high)
        {
            pivot = Partition(k, low, high);
            QuickSort(k, low, pivot - 1);   //对枢纽左侧递归排序
            QuickSort(k, pivot + 1, high);  //对枢纽右侧递归排序
        }
    }
    
    int main()
    {
        int i;
        int a[10] = { 5, 2, 6, 0, 3, 9, 1, 7, 4, 8 };
        QuickSort(a, 0, 9);
    
        for (i = 0; i < 10; i++)
            printf_s("%d ", a[i]);
    
        return 1;
    }

    改进1:三数取中,取三个关键字先解析排序,将中间数作为枢轴,一般取左端,右端和中间三个数

    如果我们选取的枢轴值正好是处于整个序列大小的中间位置,那么可以将序列分为小数集合和大数集合。但是若是我们第一个选取的是最大值呢?我们交换后实质变化并不大

    int Partition(int k[], int low, int high)
    {
        int pivotkey;
        int m = low + (high - low) / 2;
        //三数取中的判断
        if (k[low] > k[high])
            swap(k, low, high);
        if (k[m] > k[high])
            swap(k, m, high);
        if (k[m] < k[low])
            swap(k, m, low);
        //此时m处是三个数中间值
    
        pivotkey = k[m];    //用子表第一个记录左枢轴记录
        while (low < high)    //从表的两端交替向中间扫描
        {
            while (low < high && k[high] >= pivotkey)
                high--;
            swap(k, high, low);    //将比枢轴记录小的记录交换到低端
            while (low < high && k[low] <= pivotkey)
                low++;
            swap(k, low, high);    //将比枢轴记录大的记录交换到高端
        }
        return low;    //返回枢轴所在位置
    }

    改进二、优化小数组:当数组非常小时,使用快排还不如直接插入的性能好,二这个数组大小的阈值我们一般选取7最好

    #define MAX_LENGTH_INSERT_SORT 7    //数组阈值大小
    
    void InsertSort(int k[], int n)    //对数组部分进行快排
    {
        int i, j, temp;
        for (i = 1; i < n;i++)
        {
            if (k[i]<k[i-1])
            {
                temp = k[i];
                for (j = i - 1; k[j] > temp; j--)
                    k[j + 1] = k[j];
                k[j + 1] = temp;
            }
        }
    }
    
    void Qsort(int k[], int low, int high)
    {
        int pivot;
        if ((high-low)>MAX_LENGTH_INSERT_SORT)    //条件是包含high>low
        {
            pivot = Partition(k, low, high);
            Qsort(k, low, pivot - 1);    //对低子表进行递归排序
            Qsort(k, pivot + 1, high);    //对高子表进行递归排序
        }
        else
        {
            InsertSort(k + low, high - low + 1);    //对数组部分进行快排
        }
    }
  • 相关阅读:
    【VUE】数据库动态渲染标签,并且动态绑定事件与激活图标
    Linux shell select
    ceph介绍和安装
    C# 保存网络图片至本地项目中
    CS229 斯坦福大学机器学习复习材料(数学基础)
    SPRING.NET FRAMEWORK 3.0 GA啦
    U盘装机神器
    一行css让网页风格变成暗黑模式
    vue3 自学(一)基础知识学习和搭建一个脚手架
    windows使用nvm管理node不同版本
  • 原文地址:https://www.cnblogs.com/lemonzhang/p/12423512.html
Copyright © 2011-2022 走看看