• 七种基础排序算法代码总汇


    1、冒泡排序

    算法详解参考:https://mp.weixin.qq.com/s/wO11PDZSM5pQ0DfbQjKRQA

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void swap(vector<int> &arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
    void BubbleSort(vector<int> &arr)
    {
        int flag = 1;   // flag标记是否继续比较元素大小,这里赋值为1是为了进入循环
        for(int i = 1; i < arr.size() && flag; i++)
        {
            flag = 0;   // 初始化为0
            for(int j = arr.size() - 1; j >= i; j--)
            {
                if(arr[j] > arr[j+1])   // 升序
                {
                    swap(arr, j+1, j);
                    flag = 1;   // 不在比较元素时 flag = 1,进入下一次循环
                }
            }
        }
    }
    
    int main()
    {
        vector<int> arr = {0, 5, 3, 4, 6, 2};
        BubbleSort(arr);
        for(int i = 0; i < arr.size(); i++)
            cout << arr[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 冒泡法排序总时间复杂度 O(n^2)
    

    2、简单选择排序

    算法详解参考:https://mp.weixin.qq.com/s/dGfh2t7xhg0wMM_DcYP1Cw

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void swap(vector<int> &arr, int i, int j)
    {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
    void SelectSort(vector<int> &arr)
    {
        int min;
        for(int i = 1; i < arr.size(); i++)
        {
            min = i;
            for(int j = i+1; j <= arr.size(); j++)
            {
                if(arr[min] > arr[j])
                    min = j;
            }
            if(i != min)
                swap(arr, i, min);
        }
    }
    
    int main()
    {
        vector<int> arr = {0, 5, 3, 4, 6, 2};
        SelectSort(arr);
        for(int i = 0; i < arr.size(); i++)
            cout << arr[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 简单选择排序总时间复杂度 O(n^2)
    // 性能略优于冒泡
    

    3、直接插入排序

    算法详解参考:https://mp.weixin.qq.com/s/McqFXkXucSZldjU46t5cdw

    #include <iostream>
    #include <vector>
    
    using std::cout;
    using std::endl;
    using std::vector;
    
    void swap(vector<int> &arr, int i, int j)
    {
        int a = arr[i];
        arr[i] = arr[j];
        arr[j] = a;
    }
    
    void InsertSort(vector<int> &arr)
    {
        for(int i = 1; i < arr.size(); i++)
        {
            int j = i;
            while (j > 0 && arr[j] < arr[j-1])
            {
                swap(arr, j, j-1);
                j--;
            }
            
        }
    }
    
    int main()
    {
        vector<int> arr = {0, 5, 3, 4, 6, 2};
        InsertSort(arr);
        for(int i = 0; i < arr.size(); i++)
            cout << arr[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 直接插入排序总时间复杂度 O(n^2)
    // 性能优于冒泡和简单选择排序
    

    4、希尔排序

    算法详解参考:https://mp.weixin.qq.com/s/b9-dkpAhWJYshuSs5cwnOw

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void ShellSort(vector<int> &arr)
    {
        int increment = arr.size();     // 希尔排序的增量初始化
        while (increment > 1)
        {
            increment /= 2;     // 增量折半
            for(int i = 0; i < increment; i++)
            {
                for(int j = i+increment; j < arr.size(); j = j+increment)
                {
                    int temp = arr[j];
                    int k = 0;
                    for(k = j-increment; k >= 0 && arr[k] > temp; k = k-increment)
                        arr[k + increment] = arr[k];    // 由于 k 的值发生了更新,但是在此循环结束之前索引 j 是没有发生变化的,所以 k + increment != j(第一次循环时 k+increment = j)
                    arr[k + increment] = temp;
                }
            }
        }
    }
    
    int main()
    {
        vector<int> arr = {5, 8, 6, 3, 9, 2, 1, 7};
        ShellSort(arr);
        for(int i = 0; i < arr.size(); i++)
            cout << arr[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 希尔排序是不稳定排序
    // Hibbard增量序列:最坏时间复杂度 O(n^(3/2))
    // Sedgewick增量序列:最坏时间复杂度 O(n^(4/3))
    

    5、堆排序

    算法详解参考:https://mp.weixin.qq.com/s/8Bid1naBLtEjPoP-R4HkBg

    #include <iostream>
    #include <vector>
    using namespace std;
    
    // 大顶堆调整
    void adjustHeap(vector<int> &arr, int i, int length)
    {
        int temp = arr[i];      // 先取出当前元素 i
        for(int k = i*2 + 1; k < length; k = k*2 + 1)   // 从 i 结点左子节点开始,也就是 2i+1 处开始
        {
            if(k+1 < length && arr[k] < arr[k+1])   // 如果左子节点小于右子节点,k指向右子节点
                k++;
            if(arr[k] > temp)   // 如果子节点大于父节点,将子节点赋值给父节点(不用交换)
            {
                arr[i] = arr[k];
                i = k;
            }
            else break;
        }
        arr[i] = temp;  // 将 temp 值放到最终位置
    }
    // 元素交换
    void swap(vector<int> &arr, int i, int j)
    {
        int a = arr[i];
        arr[i] = arr[j];
        arr[j] = a;
    }
    
    void heapSort(vector<int> &arr)
    {
        // 构建大顶堆
        for(int i = arr.size()/2 - 1; i >= 0; i--)
            // 从第一个非叶子结点从上至下,从右到左调整结构
            adjustHeap(arr, i, arr.size());
        // 调整堆结构加交换堆顶元素与末尾元素
        for(int j = arr.size() - 1; j > 0; j--)
        {
            swap(arr, 0, j);        // 将堆顶元素与末尾元素进行交换
            adjustHeap(arr, 0, j); // 重新调整堆结构
        }
    }
    
    int main()
    {
        vector<int> arr = {5, 8, 6, 3, 9, 2, 1, 7};
        heapSort(arr);
        for(int i = 0; i < arr.size(); i++)
            cout << arr[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 堆排序整体时间复杂度 O(nlogn)
    

    6、归并排序

    算法详解参考:https://mp.weixin.qq.com/s/885uGVhlffWAxjgIEW-TiA

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void merge(vector<int> &arr, int start, int mid, int end)
    {
        // 开辟额外大集合,设置指针
        vector<int> tempArray((end - start + 1), 0);
        int p1 = start, p2 = mid+1, p = 0;
        // 比较两个小集合的元素,依次放入大集合
        while(p1 <= mid && p2 <= end)
        {
            if(arr[p1] <= arr[p2])
                tempArray[p++] = arr[p1++];
            else
                tempArray[p++] = arr[p2++];
        }
        // 左(右)侧小集合有剩余,依次放入大集合尾部
        while(p1 <= mid)
            tempArray[p++] = arr[p1++];
        while(p2 <= end)
            tempArray[p++] = arr[p2++];
        // 把大集合元素赋值回原数组
        for(int i = 0; i < tempArray.size(); i++)
            arr[i+start] = tempArray[i];
    }
    
    void mergeSort(vector<int> &arr, int start, int end)
    {
        if(start < end)
        {
            // 折半成两个小集合,分别进行递归
            int mid = (start + end) / 2;
            mergeSort(arr, start, mid);
            mergeSort(arr, mid+1, end);
            // 把两个有序小集合归并成一个大集合
            merge(arr, start, mid, end);
        }
    }
    
    int main()
    {
        vector<int> arr = {5, 8, 6, 3, 9, 2, 1, 7};
        mergeSort(arr, 0, arr.size() - 1);
        for(int i = 0; i < arr.size(); i++)
            cout << arr[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 总时间复杂度 O(nlogn)
    

    7、快速排序

    算法详解参考:https://zhuanlan.zhihu.com/p/93129029

    // 快排递归实现
    #include <iostream>
    using namespace std;
    
    void quickSort(int *arr, int begin, int end)
    {
        if(begin < end)
        {
            int temp = arr[begin];
            int i = begin;
            int j = end;
            while(i < j)
            {
                while(i < j && arr[j] > temp)
                    j--;
                arr[i] = arr[j];
                while(i < j && arr[i] <= temp)
                    i++;
                arr[j] = arr[i];
            }
            arr[i] = temp;
            // 递归排序基准数两边子集
            quickSort(arr, begin, i-1);
            quickSort(arr, i+1, end);
        }
        else return;
    }
    int main()
    {
        int num[10] = {23, 14, 5, 7, 29, 50, 11, 33, 10, 8};
        cout << "排序前: " << endl;
        for(int i = 0; i < 10; i++)
            cout << num[i] << " ";
        cout << endl;
        quickSort(num, 0, 9);
        cout << "排序后: " << endl;
        for(int i = 0; i < 10; i++)
            cout << num[i] << " ";
        cout << endl;
        return 0;
    }
    
    // 快速排序时间复杂度 O(nlog2N)
    
  • 相关阅读:
    局部变量的认识
    179一个错误的认识
    (jmeter笔记) websocket接口测试
    (jmeter笔记)聚合报告分析
    (jmeter笔记)模拟用户各种场景压测
    (linux笔记)开放防火墙端口
    (jmeter笔记)导出响应内容的网络文件
    (jmeter笔记)jmeter导出excel,中文显示乱码
    (jmeter笔记)jmeter监控服务器资源
    (Jmeter笔记)jmeter连接数据库(mysql)
  • 原文地址:https://www.cnblogs.com/horacle/p/13400108.html
Copyright © 2020-2023  润新知