【C++】十大排序算法(亲测有效!)

背景

        网上很多排序算法运行结果是错误的,本小白很苦恼,因此花了一些时间汇总了各个算法,并给出main函数调用方式,本文仅为了分享个人学习记录,如有错误,欢迎讨论!

        本文的代码均已在Visual Studio测试过,可放心ctrl C!具体每种算法的介绍与展开,后续有时间进行补充!

1.冒泡排序

void bubbleSort(int Array[], int ArraySize) {
    for (int i = 0; i < ArraySize - 1; i++) {
        for (int j = 0; j < ArraySize - 1 - i; j++) {
            if (Array[j] > Array[j + 1]) {
                int Temp = Array[j];
                Array[j] = Array[j + 1];
                Array[j + 1] = Temp;
            }
        }
    }
}

1.1.冒泡排序优化版

void bubbleSortAdvanced(int Array[], int ArraySize) {
    bool SwapFlag = false;
    for (int i = 0; i < ArraySize - 1; i++) {
        SwapFlag = false;
        for (int j = 0; j < ArraySize - 1 - i; j++) {
            if (Array[j] > Array[j + 1]) {
                swap(Array[j], Array[j + 1]);
                SwapFlag = true;
            }
        }
        if (SwapFlag == false) 
            break;
    }
}

2.选择排序

void selectSort(int Array[], int ArraySize) {
    for (int i = 0; i < ArraySize - 1; i++) {
        int Index = i;
        for (int j = i + 1; j < ArraySize; j++) {
            if (Array[j] < Array[Index]) 
                Index = j;
        }
        swap(Array[Index], Array[i]);
    }
}

3.插入排序

void insertSort(int Array[], int ArraySize) {
    for (int i = 1; i < ArraySize; i++) {
        for (int j = i; j > 0; j--) {
            if (Array[j - 1] > Array[j]) 
                swap(Array[j - 1], Array[j]);
            else
                break;
        }
    }
}

4.快速排序

void quickSort(int Array[], int ArraySize, int Left, int Right) {
    if (Left >= Right) return;
    int i = Left, j = Right, Base = Array[Left];
    while (i < j) {
        while (Array[j] >= Base && i < j) 
            j--;
        while (Array[i] <= Base && i < j) 
            i++;
        if (i < j) 
            swap(Array[i], Array[j]);
    }
    Array[Left] = Array[i];
    Array[i] = Base;
    quickSort(Array, ArraySize, Left, i - 1);
    quickSort(Array, ArraySize, i + 1, Right);
}

5.希尔排序

void shellSort(int Array[], int ArraySize) {
    for (int i = 0; i < ArraySize; i++) {
        for (int j = i - 1; j >= 0 && Array[j + 1] < Array[j]; j--) {
            swap(Array[j], Array[j + 1]);
        }
    }
}

6.归并排序

void mergeArray(int Array[], int ArraySize, int Left, int Middle, int Right) {
    int LeftSize = Middle - Left + 1, RightSize = Right - Middle;
    // 创建临时数组来保存左右两部分的数据
    vector<int> LeftTempArray(LeftSize), RightTempArray(RightSize);
    // 将数据复制到临时数组中
    for (int i = 0; i < LeftSize; ++i)
        LeftTempArray[i] = Array[Left + i];
    for (int j = 0; j < RightSize; ++j)
        RightTempArray[j] = Array[Middle + 1 + j];

    // 将临时数组中的数据按顺序合并到原始数组中
    int i = 0, j = 0, k = Left;
    while (i < LeftSize && j < RightSize) {
        if (LeftTempArray[i] <= RightTempArray[j]) {
            Array[k] = LeftTempArray[i];
            i++;
        }
        else {
            Array[k] = RightTempArray[j];
            j++;
        }
        k++;
    }
    // 将剩余的元素复制到原始数组中
    while (i < LeftSize) {
        Array[k] = LeftTempArray[i];
        i++; 
        k++;
    }
    while (j < RightSize) {
        Array[k] = RightTempArray[j];
        j++; 
        k++;
    }
}
static void mergeSort(int Array[], int ArraySize, int Left, int Right) {
    if (Left >= Right) 
        return;
    int Middle = Left + ((Right - Left) / 2);
    mergeSort(Array, ArraySize, Left, Middle);
    mergeSort(Array, ArraySize, Middle + 1, Right);
    mergeArray(Array, ArraySize, Left, Middle, Right);
}

7.堆排序

void heapSort_MaxTree(int Array[], int StartIndex, int EndIndex) {
    int ParentIndex = StartIndex;           /* 父节点 */
    int ChildIndex = 2 * StartIndex + 1;    /* 子节点 */
    while (ChildIndex < EndIndex) {
        // 判断挑出 大的子节点 与 父节点 比较
        if (ChildIndex + 1 < EndIndex && Array[ChildIndex] < Array[ChildIndex + 1])       
            ChildIndex++;
        // 若父节点>子节点,则调整完毕.否则继续调整
        if (Array[ParentIndex] > Array[ChildIndex]) 
            return;
        else {
            // 交换父 子节点
            swap(Array[ParentIndex], Array[ChildIndex]);
            ParentIndex = ChildIndex;
            ChildIndex = 2 * ChildIndex + 1;
        }
    }
}
static void heapSort(int Array[], int ArraySize) {
    // 数组初始化:构建大顶堆
    for (int i = ArraySize / 2 - 1; i >= 0; i--) {
        heapSort_MaxTree(Array, i, ArraySize);// 从倒数一半的位置开始,后面的均为最底层树
    }
    // 依次排序并调整:从最后一个元素开始,不断缩小调整范围到第一个元素
    for (int i = ArraySize - 1; i > 0; i--) {
        // 交换Array[0]和Array[i],交换后Array[i]是Array[0到i]中最大的
        swap(Array[0], Array[i]);
        // 调整Array[0......i],使其仍为最大堆
        heapSort_MaxTree(Array, 0, i);
    }
}

8.桶排序

static int digitCount(long long Number) {
    int Counter = 1;
    while (Number /= 10) 
        Counter++;
    return Counter;
}
static void bucketSort(int Array[], int ArraySize) {
    // 获取最小值 最大值 确定桶的个数
    int MinValue = Array[0], MaxValue = Array[0];
    for (int i = 0; i < ArraySize; i++) {
        if (MinValue > Array[i]) 
            MinValue = Array[i];
        if (MaxValue < Array[i]) 
            MaxValue = Array[i];
    }
    // 根据位数来创建桶的个数
    int BucketNum = digitCount(MaxValue);
    double BucketRange = (double)(MaxValue - MinValue + 1) / BucketNum;
    vector<vector<int>> Buckets(BucketNum);
    // 初始化桶空间
    for (int i = 0; i < BucketNum; i++) {
        Buckets[i].reserve(ArraySize / BucketNum);
    }
    // 将元素放入对应的桶中
    for (int i = 0; i < ArraySize; ++i) {
        int BucketIndex = (int)((Array[i] - MinValue) / BucketRange);
        Buckets[BucketIndex].push_back(Array[i]);
    }
    // 对桶内的元素进行排序
    for (int i = 0; i < BucketNum; ++i) 
        sort(Buckets[i].begin(), Buckets[i].end());
    // 将桶中的元素按顺序合并得到排序结果
    int index = 0;
    for (int i = 0; i < BucketNum; ++i) {
        for (int j = 0; j < Buckets[i].size(); ++j) 
            Array[index++] = Buckets[i][j];
    }
}

9.计数排序

void countSort(int Array[], int ArraySize) {
    // 找出最大值与最小值
    int Min = Array[0], Max = Array[0];
    for (int i = 0; i < ArraySize; i++) {
        if (Min > Array[i]) 
            Min = Array[i];
        if (Max < Array[i]) 
            Max = Array[i];
    }
    // 根据最大值与最小值之间的元素个数开辟新数组
    vector<int> Count(Max - Min + 1, 0);
    for (int i = 0; i < ArraySize; i++) {
        // 统计相同元素出现的次数
        int OffSet = Array[i] - Min;
        Count[OffSet]++;
    }
    for (int i = 0, Position = 0; i < Count.size(); i++) {
        while ((Count[i]--) != 0) {
            Array[Position] = i + Min;
            Position++;
        }
    }
}

10.基数排序

int maxBit(int Array[], int ArraySize) {
    int MaxValue = Array[0];
    for (int i = 0; i < ArraySize; i++) {
        if (MaxValue < Array[i]) 
            MaxValue = Array[i];
    }
    int Counter = 1;    // 最大位数
    int Max = 10;
    while (MaxValue >= Max) {
        MaxValue /= 10;
        Counter++;
    }
    return Counter;
}
void radixSort(int Array[], int ArraySize) {
    // 十进制数,所以为10
    int MaxCounter = maxBit(Array, ArraySize);
    int *Temp = new int[ArraySize];
    int *Count = new int[10];   // 计数器
    int Radix = 1;
    // MaxCounter次排序
    for (int i = 1; i <= MaxCounter; i++) { 
        // 每次分配前清空计数器
        for (int j = 0; j < 10; j++) 
            Count[j] = 0;
        // 统计每个桶中的记录数
        for (int j = 0; j < ArraySize; j++) {
            int k = (Array[j] / Radix) % 10;
            Count[k]++;
        }
        // 将Temp中的位置依次分配给每个桶
        for (int j = 1; j < 10; j++) 
            Count[j] = Count[j - 1] + Count[j];
        // 将所有桶中记录依次收集到tmp中
        for (int j = ArraySize - 1; j >= 0; j--) {
            int k = (Array[j] / Radix) % 10;
            Temp[Count[k] - 1] = Array[j];
            Count[k]--;
        }
        // 将临时数组Temp的内容复制到Array中
        for (int j = 0; j < ArraySize; j++) 
            Array[j] = Temp[j];
        Radix = Radix * 10;
    }
}

AC代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

/* 1.冒泡排序(稳定):相邻元素相等时,它们并不会交换位置;时间复杂度O(n^2) */
void bubbleSort(int Array[], int ArraySize) {
    for (int i = 0; i < ArraySize - 1; i++) {
        for (int j = 0; j < ArraySize - 1 - i; j++) {
            if (Array[j] > Array[j + 1]) {
                int Temp = Array[j];
                Array[j] = Array[j + 1];
                Array[j + 1] = Temp;
            }
        }
    }
}

/* 1.1.冒泡排序(优化):提升稳定性.有序时,时间复杂度为O(n) */
void bubbleSortAdvanced(int Array[], int ArraySize) {
    bool SwapFlag = false;
    for (int i = 0; i < ArraySize - 1; i++) {
        SwapFlag = false;
        for (int j = 0; j < ArraySize - 1 - i; j++) {
            if (Array[j] > Array[j + 1]) {
                swap(Array[j], Array[j + 1]);
                SwapFlag = true;
            }
        }
        if (SwapFlag == false) 
            break;
    }
}

/* 2.选择排序(不稳定):记录最大元素及下标,遍历后调换元素位置.时间复杂度为O(n^2) */
void selectSort(int Array[], int ArraySize) {
    for (int i = 0; i < ArraySize - 1; i++) {
        int Index = i;
        for (int j = i + 1; j < ArraySize; j++) {
            if (Array[j] < Array[Index]) 
                Index = j;
        }
        swap(Array[Index], Array[i]);
    }
}

/* 3.插入排序:循环比较,每发现1个数,就开始调位.时间复杂度为O(n^2)*/
void insertSort(int Array[], int ArraySize) {
    for (int i = 1; i < ArraySize; i++) {
        for (int j = i; j > 0; j--) {
            if (Array[j - 1] > Array[j]) 
                swap(Array[j - 1], Array[j]);
            else 
                break;
        }
    }
}

/* 4.快速排序:分为两半部分,进行递归.时间复杂度为O(nlogn) */
void quickSort(int Array[], int ArraySize, int Left, int Right) {
    if (Left >= Right) return;
    int i = Left, j = Right, Base = Array[Left];
    while (i < j) {
        while (Array[j] >= Base && i < j) 
            j--;
        while (Array[i] <= Base && i < j) 
            i++;
        if (i < j) 
            swap(Array[i], Array[j]);
    }
    Array[Left] = Array[i];
    Array[i] = Base;
    quickSort(Array, ArraySize, Left, i - 1);
    quickSort(Array, ArraySize, i + 1, Right);
}

/* 5.希尔排序(非稳定):插入排序的改进,循环比较,每发现一个数,就开始调位.时间复杂度为O(n^2) */
void shellSort(int Array[], int ArraySize) {
    for (int i = 0; i < ArraySize; i++) {
        for (int j = i - 1; j >= 0 && Array[j + 1] < Array[j]; j--) {
            swap(Array[j], Array[j + 1]);
        }
    }
}

/* 6.归并排序(稳定):递归将1个数组分成2部分分别排序.时间复杂度O(nlogn) */
void mergeArray(int Array[], int ArraySize, int Left, int Middle, int Right) {
    int LeftSize = Middle - Left + 1, RightSize = Right - Middle;
    // 创建临时数组来保存左右两部分的数据
    vector<int> LeftTempArray(LeftSize), RightTempArray(RightSize);
    // 将数据复制到临时数组中
    for (int i = 0; i < LeftSize; ++i)
        LeftTempArray[i] = Array[Left + i];
    for (int j = 0; j < RightSize; ++j)
        RightTempArray[j] = Array[Middle + 1 + j];

    // 将临时数组中的数据按顺序合并到原始数组中
    int i = 0, j = 0, k = Left;
    while (i < LeftSize && j < RightSize) {
        if (LeftTempArray[i] <= RightTempArray[j]) {
            Array[k] = LeftTempArray[i];
            i++;
        }
        else {
            Array[k] = RightTempArray[j];
            j++;
        }
        k++;
    }
    // 将剩余的元素复制到原始数组中
    while (i < LeftSize) {
        Array[k] = LeftTempArray[i];
        i++; 
        k++;
    }
    while (j < RightSize) {
        Array[k] = RightTempArray[j];
        j++; 
        k++;
    }
}
void mergeSort(int Array[], int ArraySize, int Left, int Right) {
    if (Left >= Right) 
        return;
    int Middle = Left + ((Right - Left) / 2);
    mergeSort(Array, ArraySize, Left, Middle);
    mergeSort(Array, ArraySize, Middle + 1, Right);
    mergeArray(Array, ArraySize, Left, Middle, Right);
}

/* 7.堆排序(不稳定):近似完全二叉树,子节点的键值或索引总<(>)其父节点 */
void heapSort_MaxTree(int Array[], int StartIndex, int EndIndex) {
    int ParentIndex = StartIndex;           /* 父节点 */
    int ChildIndex = 2 * StartIndex + 1;    /* 子节点 */
    while (ChildIndex < EndIndex) {
        // 判断挑出 大的子节点 与 父节点 比较
        if (ChildIndex + 1 < EndIndex && Array[ChildIndex] < Array[ChildIndex + 1]) 
            ChildIndex++;
        // 若父节点>子节点,则调整完毕.否则继续调整
        if (Array[ParentIndex] > Array[ChildIndex]) 
            return;
        else {
            // 交换父 子节点
            swap(Array[ParentIndex], Array[ChildIndex]);
            ParentIndex = ChildIndex;
            ChildIndex = 2 * ChildIndex + 1;
        }
    }
}
void heapSort(int Array[], int ArraySize) {
    // 数组初始化:构建大顶堆
    for (int i = ArraySize / 2 - 1; i >= 0; i--) {
        heapSort_MaxTree(Array, i, ArraySize);// 从倒数一半的位置开始,后面的均为最底层树
    }
    // 依次排序并调整:从最后一个元素开始,不断缩小调整范围到第一个元素
    for (int i = ArraySize - 1; i > 0; i--) {
        // 交换Array[0]和Array[i],交换后Array[i]是Array[0到i]中最大的
        swap(Array[0], Array[i]);
        // 调整Array[0......i],使其仍为最大堆
        heapSort_MaxTree(Array, 0, i);
    }
}

/* 8.桶排序:将待排序数组映射到不同的桶内,保证桶内有序,再反向输出 */
int digitCount(long long Number) {
    int Counter = 1;
    while (Number /= 10) Counter++;
    return Counter;
}
void bucketSort(int Array[], int ArraySize) {
    // 获取最小值 最大值 确定桶的个数
    int MinValue = Array[0], MaxValue = Array[0];
    for (int i = 0; i < ArraySize; i++) {
        if (MinValue > Array[i]) 
            MinValue = Array[i];
        if (MaxValue < Array[i]) 
            MaxValue = Array[i];
    }
    // 根据位数来创建桶的个数
    int BucketNum = digitCount(MaxValue);
    double BucketRange = (double)(MaxValue - MinValue + 1) / BucketNum;
    vector<vector<int>> Buckets(BucketNum);
    // 初始化桶空间
    for (int i = 0; i < BucketNum; i++) {
        Buckets[i].reserve(ArraySize / BucketNum);
    }
    // 将元素放入对应的桶中
    for (int i = 0; i < ArraySize; ++i) {
        int BucketIndex = (int)((Array[i] - MinValue) / BucketRange);
        Buckets[BucketIndex].push_back(Array[i]);
    }
    // 对桶内的元素进行排序
    for (int i = 0; i < BucketNum; ++i) 
        sort(Buckets[i].begin(), Buckets[i].end());
    // 将桶中的元素按顺序合并得到排序结果
    int index = 0;
    for (int i = 0; i < BucketNum; ++i) {
        for (int j = 0; j < Buckets[i].size(); ++j) 
            Array[index++] = Buckets[i][j];
    }
}

/* 9.计数排序:开辟新的数组;原数组值映射为新数组的键值,原数组值的个数为新数组的数值 */
void countSort(int Array[], int ArraySize) {
    // 找出最大值与最小值
    int Min = Array[0], Max = Array[0];
    for (int i = 0; i < ArraySize; i++) {
        if (Min > Array[i]) 
            Min = Array[i];
        if (Max < Array[i]) 
            Max = Array[i];
    }
    // 根据最大值与最小值之间的元素个数开辟新数组
    vector<int> Count(Max - Min + 1, 0);
    for (int i = 0; i < ArraySize; i++) {
        // 统计相同元素出现的次数
        int OffSet = Array[i] - Min;
        Count[OffSet]++;
    }
    for (int i = 0, Position = 0; i < Count.size(); i++) {
        while ((Count[i]--) != 0) {
            Array[Position] = i + Min;
            Position++;
        }
    }
}

/* 10.基数排序(稳定):将数字按个十百分开,每位进行比较 */
int maxBit(int Array[], int ArraySize) {
    int MaxValue = Array[0];
    for (int i = 0; i < ArraySize; i++) {
        if (MaxValue < Array[i]) 
            MaxValue = Array[i];
    }
    int Counter = 1;    // 最大位数
    int Max = 10;
    while (MaxValue >= Max) {
        MaxValue /= 10;
        Counter++;
    }
    return Counter;
}
void radixSort(int Array[], int ArraySize) {
    // 十进制数,所以为10
    int MaxCounter = maxBit(Array, ArraySize);
    int *Temp = new int[ArraySize];
    int *Count = new int[10];   // 计数器
    int Radix = 1;
    // MaxCounter次排序
    for (int i = 1; i <= MaxCounter; i++) { 
        // 每次分配前清空计数器
        for (int j = 0; j < 10; j++) 
            Count[j] = 0;
        // 统计每个桶中的记录数
        for (int j = 0; j < ArraySize; j++) {
            int k = (Array[j] / Radix) % 10;
            Count[k]++;
        }
        // 将Temp中的位置依次分配给每个桶
        for (int j = 1; j < 10; j++) 
            Count[j] = Count[j - 1] + Count[j];
        // 将所有桶中记录依次收集到tmp中
        for (int j = ArraySize - 1; j >= 0; j--) {
            int k = (Array[j] / Radix) % 10;
            Temp[Count[k] - 1] = Array[j];
            Count[k]--;
        }
        // 将临时数组Temp的内容复制到Array中
        for (int j = 0; j < ArraySize; j++) 
            Array[j] = Temp[j];
        Radix = Radix * 10;
    }
}

template<typename T_Whz>
void myPrintf(T_Whz Array[], T_Whz ArraySize) {
    for (int i = 0; i < ArraySize; i++) {
        cout << Array[i] << ' ';
    }
    cout << endl;
}

int main() {
    int Array[] = { 9,1,5,8,3,7,4,6,2 };
    int ArraySize = sizeof(Array) / sizeof(Array[0]);
    cout << "Before Sort:" << endl;
    myPrintf(Array, ArraySize);

    radixSort(Array, ArraySize);
    cout << "After Sort:" << endl;
    myPrintf(Array, ArraySize);

    mergeSort(Array, ArraySize, 0, ArraySize - 1);
    cout << "After quickSort:" << endl;
    myPrintf(Array, ArraySize);

    system("pause");
    return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
对于十大排序算法中的堆排序、选择排序和冒泡排序算法的C语言实现,可以参考如下代码: 堆排序: ```c void heapify(int *vec, int i, int len) { int left = i * 2 + 1; int right = i * 2 + 2; int largest = i; if (left < len && vec[left > vec[largest]) { largest = left; } if (right < len && vec[right > vec[largest]) { largest = right; } if (largest != i) { int temp = vec[i]; vec[i = vec[largest]; vec[largest = temp; heapify(vec, largest, len); } } void heapSort(int *vec, int len) { for (int i = len / 2 - 1; i >= 0; i--) { heapify(vec, i, len); } for (int j = len - 1; j > 0; j--) { int temp = vec = vec[j]; vec[j = temp; heapify(vec, 0, j); } } ``` 选择排序: ```c void selectionSort(int *vec, int len) { for (int i = 0; i < len - 1; i++) { int minIndex = i; for (int j = i + 1; j < len; j++) { if (vec[j < vec[minIndex]) { minIndex = j; } } if (minIndex != i) { int temp = vec[i]; vec[i = vec[minIndex]; vec[minIndex = temp; } } } ``` 冒泡排序: ```c void bubbleSort(int *vec, int len) { for (int i = 1; i < len; i++) { for (int j = 0; j < len - i; j++) { if (vec[j > vec[j + 1]) { int temp = vec[j]; vec[j = vec[j + 1]; vec[j + 1 = temp; } } } } ``` 这些代码分别实现了堆排序、选择排序和冒泡排序算法,可以通过传入一个整型数组和数组长度来对数组进行排序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [用C++实现十大经典排序算法](https://blog.csdn.net/qq_34139994/article/details/128217009)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.239^v12^insert_chatgpt"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颜值国家队

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值