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

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)

猜你喜欢

转载自www.cnblogs.com/horacle/p/13400108.html