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;
}

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

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页