zoukankan      html  css  js  c++  java
  • Algorithm:十大经典排序算法C++实现及总结

    算法性能总结

    在这里插入图片描述

    1、冒泡排序

    在这里插入图片描述

    //1、Bubble Sort 冒泡排序
    void bubbleSort(int a[], int length)
    {
        if (length < 2)
            return;
        for (int i = 0; i < length - 1; i++) //需length-1趟排序确定后length-1个数,剩下第一个数不用排序;
        {
            for (int j = 0; j < length - 1 - i; j++)
            {
                if (a[j + 1] < a[j])
                {
                    int temp = a[j + 1];
                    a[j + 1] = a[j];
                    a[j] = temp;
                }
            }
        }
    }
    

    2、选择排序

    在这里插入图片描述

    //2、Select Sort 选择排序
    void selectSort(int a[], int length)
    {
        if (length < 2)
            return;
        for (int i = 0; i < length; i++)
        {
            int minIndex = i;
            for (int j = i + 1; j < length; j++) //已确定a[0]~a[i-1],从i-1开始查找最小的数,然后与a[i]交换位置;
            {
                if (a[j] < a[minIndex])
                    minIndex = j;
            }
            int temp = a[i];
            a[i] = a[minIndex];
            a[minIndex] = temp;
        }
    }
    

    3、插入排序

    在这里插入图片描述

    //3、Insert Sort 插入排序
    void insertSort(int a[], int length)
    {
        if (length < 2)
            return;
        for (int i = 1; i < length; i++) //现在进行插入的是a[i]
        {
            int cur = a[i];
            int j = i;
            while (j > 0 && a[j - 1] > cur) //如果前面的数比cur,说明cur要插在它们前面,即将它们后移一个位置;
            {
                a[j] = a[j - 1];
                j--;
            }
            a[j] = cur;
        }
    }
    

    4、希尔排序

    在这里插入图片描述

    //4、Shell Sort 希尔排序
    void shellSort(int a[], int length)
    {
        if (length < 2)
            return;
        int gap = length / 2; //整个数组分为gap个组,即每隔 gap-1 个位置的元素为一组
        while (gap > 0)       //最终整个数组分为一组 即所有元素为一组;
        {
            for (int i = gap; i < length; i++)
            {
                int cur = a[i];
                int preIndex = i - gap;
                while (preIndex >= 0 && a[preIndex] > cur) //对每一组元素进行插入排序
                {
                    a[i] = a[preIndex];
                    preIndex -= gap;
                }
                a[preIndex + gap] = cur;
            }
            gap /= 2;
        }
    }
    

    5、归并排序

    在这里插入图片描述

    //5、Merge Sort 归并排序
    void merge(int a[], int left, int mid, int right);
    
    void mergeSort(int a[], int left, int right) //  left需要排序数组 a[] 的左端下标,right为右端下标
    {
        int length = right - left + 1;
        if (length < 2)
            return;
    
        int mid = (right + left) / 2;
    
        mergeSort(a, 0, mid);
        mergeSort(a, mid + 1, right);
        merge(a, left, mid, right); //调用merge函数 将二者合并
    }
    
    void merge(int a[], int left, int mid, int right) //将数组a 的两个子数组a[left] ~ a[mid] 与 a[mid+1] ~ a[right] 合并
    {
        int len = right - left + 1;
    
        vector<int> temp;
        int i = left, j = mid + 1;
        for (; i <= mid && j <= right;)
        {
            if (a[i] < a[j])
            {
                temp.push_back(a[i]);
                i++;
            }
            else
            {
                temp.push_back(a[j]);
                j++;
            }
        }
        while (i <= mid)
            temp.push_back(a[i++]); //此时必有一个子数组没有走完 需要把剩下的元素全部放进vector
        while (j <= right)
            temp.push_back(a[j++]);
    
        for (int i = left, k = 0; i <= right; i++) //把vector中已排完序的元素存入数组a[left]~a[right]
        {
            a[i] = temp[k++];
        }
    }
    

    6、快速排序

    在这里插入图片描述

    //6、Quick Sort 快速排序
    void quickSort(int a[], int left, int right)
    {
        if (left >= right)
            return;
        int key = a[left]; //以第一个数为基数进行快排;
        int pointL = left, pointR = right;
    
        while (pointL < pointR)
        {
            //一定要先动右指针,否则右指针所指向的元素无处存放
            while (pointR > pointL && a[pointR] >= key) //若右指针指向的元素大于key 则右指针左移,直到右指针指向的元素小于key 或者 左右指针坐标相同
                pointR--;
            a[pointL] = a[pointR]; //把这个小于key的元素放到key的左边,即左指针指向的位置
    
            while (pointR > pointL && a[pointL] <= key) //若左指针指向的元素小于key 则左指针右移,直到左指针指向的元素大于key 或者 左右指针坐标相同
                pointL++;
            a[pointR] = a[pointL]; //把这个大于key的元素放到key的右边,即右指针指向的位置
        }
        a[pointR] = key; //此时左右指针指向同一位置,这个位置就是key应该放的位置
    
        //对key两边的元素同样使用快排
        quickSort(a, left, pointR - 1);
        quickSort(a, pointR + 1, right);
    }
    

    7、计数排序

    在这里插入图片描述

    //7、Counting Sort 计数排序
    void countingSort(int a[], int length)
    {
        if (length < 2)
            return;
        int min = a[0], max = a[0];
        int bios; //偏移量
    
        for (int i = 0; i < length; i++) //找最大最小值
        {
            if (a[i] < min)
                min = a[i];
            if (a[i] > max)
                max = a[i];
        }
    
        bios = 0 - min;
        vector<int> temp(max - min + 1, 0);
    
        for (int i = 0; i < length; i++) //把出现了的元素作为temp的下标 并置1;
        {
            temp[a[i] + bios]++;
        }
    
        int index = 0;
        for (int i = 0; i < max - min + 1; i++) //顺序扫描以便vector即可
        {
            while (temp[i])
            {
                a[index++] = i - bios;
                temp[i]--;
            }
        }
    }
    

    8、桶排序

    在这里插入图片描述

    //8、Bucket Sort 桶排序
    void bucketSort(int a[], int length)
    {
        if (length < 2)
            return;
        int min = a[0], max = a[0];
        for (int i = 0; i < length; i++)
        {
            if (a[i] < min)
                min = a[i];
            if (a[i] > max)
                max = a[i];
        }
    
        int buckNum = (max - min) / length + 1; //桶的数量
        vector<vector<int>> bucketArr;
        for (int i = 0; i < buckNum; i++)
        {
            vector<int> temp;
            bucketArr.push_back(temp);
        }
    
        //每个元素入桶
        for (int i = 0; i < length; i++)
        {
            int num = (a[i] - min) / length;
            bucketArr[num].push_back(a[i]);
        }
    
        //对每个桶排序 并且排序完后赋值
        int index = 0;
        for (int i = 0; i < bucketArr.size(); i++)
        {
            if (bucketArr[i].size())
            {
                sort(bucketArr[i].begin(), bucketArr[i].end()); //快排
                for (int j = 0; j < bucketArr[i].size(); j++)
                {
                    a[index++] = bucketArr[i][j];
                }
            }
        }
    }
    
    

    9、基数排序

    在这里插入图片描述

    //9、Base Sort 基数排序
    void baseSort(int a[], int length) 
    {
        //得到最大位数;
        int max = a[0];
        int d = 0;//最大位数
        for (int i = 0; i < length; i++)
        {
            if (a[i] > max)
                max = a[i];
        }
        while (max)
        {
            max /= 10;
            d++;
        }
    
        int factor = 1;
        for (int i = 1; i <= d; i++) //从个位数排到d位数
        {
            vector<int> bucket[10]; //初始化十个桶
            for (int i = 0; i < length; i++)
            {
                int temp = (a[i] / factor) % 10; //得到a[i]的now_d位数,并放入对应桶中
                bucket[temp].push_back(a[i]);
            }
            int j = 0;
            for (int i = 0; i < 10; i++) //遍历十个桶,按从小到大顺序放入原数组
            {
                int size = bucket[i].size();
                for (int k = 0; k < size; k++)
                {
                    a[j++] = bucket[i][k];
                }
                bucket[i].clear(); //桶置空
            }
            factor *= 10;
        }
    }
    

    10、堆排序

    在这里插入图片描述

    //10、Heap Sort 堆排序   大顶堆做出来顺序,小顶堆做出来逆序
    void fixDown(int a[], int i, int length);
    void swap(int a[], int i, int j);
    
    void heapSort(int a[], int length)
    {
        //先对 a 堆化
        for (int i = length / 2 - 1; i >= 0; i--) // 完成后 此时a已经是合法的小顶堆
        {
            fixDown(a, i, length); //把i当前小顶堆的根节点
        }
        //调整堆结构
        for (int x = length - 1; x > 0; x--)
        {
            //把堆顶元素(0号元素)和末尾元素对调;
            swap(a, 0, x);
            //缩小堆的范围,对堆顶元素进行向下调整;
            fixDown(a, 0, x);
        }
    }
    
    void fixDown(int a[], int i, int length)
    {
        //找到左右子孩子
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int min = left;     //min指向左右孩子中较小的那个
        if (left >= length) //若左孩子越界则右孩子必越界
            return;
        if (right < length && a[right] < a[left]) //右孩子越界或者右孩子值比左孩子小
            min = right;
    
         //如果a[i]比这两个孩子的值都要小,则不用调整;
        if (a[i] < a[min])
            return;
    
        //否则,其值和a[i]交换;
        swap(a, i, min);
        //小孩子那个位置的值发生变化,i变更为小孩子的那个位置,于是递归调整;
        fixDown(a, min, length);
    }
    void swap(int a[], int i, int j)
    {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    //1、Bubble Sort 冒泡排序
    void bubbleSort(int a[], int length);
    //2、Select Sort 选择排序
    void selectSort(int a[], int length);
    //3、Insert Sort 插入排序
    void insertSort(int a[], int length);
    //4、Shell Sort 希尔排序
    void shellSort(int a[], int length);
    //5、Merge Sort 归并排序
    void merge(int a[], int left, int mid, int right);
    void mergeSort(int a[], int left, int right) ;
    //6、Quick Sort 快速排序
    void quickSort(int a[], int left, int right);
    //7、Counting Sort 计数排序
    void countingSort(int a[], int length);
    //8、Bucket Sort 桶排序
    void bucketSort(int a[], int length);
    //9、Base Sort 基数排序
    void baseSort(int a[], int length);
    //10、Heap Sort 堆排序   大顶堆做出来顺序,小顶堆做出来逆序
    void fixDown(int a[], int i, int length);
    void swap(int a[], int i, int j);
    void heapSort(int a[], int length)
    
    int main()
    {
        int a[8] = {3, 1, 5, 4, 5, 8, 7, 10};
        // bubbleSort(a, 8);
        // selectSort(a,8);
        // insertSort(a, 8);
        // shellSort(a, 8);
        // mergeSort(a, 0, 7);
        // quickSort(a, 0, 7);
        // countingSort(a, 8);
        // bucketSort(a, 8);
        // baseSort(a, 8);
        heapSort(a, 8);
        for (int i = 0; i < 8; i++)
            cout << a[i] << ' ';
    
        return 0;
    }
    
    

    如有错误,欢迎评论指正,谢谢!

  • 相关阅读:
    java架构师学习路线-HTTP请求类型及说明
    java架构师学习路线-关闭HTTP的TRACE方法
    AC自动机模板
    loj 2721 [NOI2018] 屠龙勇士
    scrum介绍
    本地搭建nacos集群
    js对象
    函数声明与表达式、匿名函数与具名函数、立即执行函数
    第六章 SSH远程服务介绍
    第十二章 配置vlan
  • 原文地址:https://www.cnblogs.com/Luweir/p/14147184.html
Copyright © 2011-2022 走看看