各种排序算法
以下排序均实现从小到大的排序,且数据相同
冒泡排序
- 重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。
| void buttle_sort(int* ar, int len) |
| { |
| int temp; |
| for (int i = 0; i < len - 1; i++) |
| { |
| for (int j = 0; j < len - i - 1; j++) |
| { |
| if (ar[j] < ar[j - 1]) |
| { |
| temp = ar[j]; |
| ar[j] = ar[j - 1]; |
| ar[j - 1] = temp; |
| } |
| } |
| } |
| } |
选择排序
- 选择排序是一种简单直观的排序算法。依次从序列中找出最小(最大)的元素,放在开头,再次寻找最小(最大)的元素,放在已排序好 的序列的末尾,以此类推
| void choice_sort(int* ar, int len) |
| { |
| int temp; |
| for (int i = 0; i < len - 1; i++) |
| { |
| int minIdx = i; |
| for (int j = i + 1; j < len; j++) |
| { |
| minIdx = (ar[minIdx] < ar[j]) ? minIdx : j; |
| } |
| temp = ar[i]; |
| ar[i] = ar[minIdx]; |
| ar[minIdx] = temp; |
| } |
| } |
插入排序
- 依次遍历元素,寻找一个合适的最小(最大)的元素,并逐个与不合适的元素交换位置,实现插入,最后将其放到一个排好序的有序列表中
| void insert_sort(int* ar, int len) |
| { |
| int temp; |
| for (int i = 1; i < len; i++) |
| { |
| temp = ar[i]; |
| int j = i; |
| while (j && ar[j - 1] > temp) |
| { |
| ar[j] = ar[j - 1]; |
| j--; |
| } |
| ar[j] = temp; |
| } |
| } |
希尔排序
- 希尔排序是快速的插入排序,通过引入step(步长)来缩插入排序的待交换位置两个元素之间的距离,并且步长依次减少
| |
| void Shell_sort(int* ar, int len) |
| { |
| |
| int step = len / 2; |
| int temp; |
| while (step) |
| { |
| for (int i = step; i < len; i += step) |
| { |
| temp = ar[i]; |
| int j = i; |
| while (j && ar[j - step] > temp) |
| { |
| ar[j] = ar[j - step]; |
| j -= step; |
| } |
| ar[j] = temp; |
| } |
| |
| step /= 2; |
| } |
| } |
计数排序
- 计数排序是最简单的排序,把元素的值直接当作下标来使用,通过元素值来形成一个新的序列,基数排序不适用于重复元素与负值元素,需要重新实现细节
| void jishu_sort(int* ar, int len, int max) |
| { |
| |
| int k = 0; |
| int lengh = max + 1; |
| |
| int* pTemp = new int[lengh]; |
| |
| |
| for (int i = 0; i < max+1; i++) |
| { |
| pTemp[i] = -999; |
| } |
| |
| for (int i = 0; i < len; i++) |
| { |
| pTemp[ar[i]] = ar[i]; |
| } |
| |
| |
| for (int i = 0; i < max+1; i++) |
| { |
| if (pTemp[i] != -999) |
| { |
| ar[k++] = pTemp[i]; |
| } |
| } |
| |
| delete[] pTemp; |
| |
| } |
桶排序
- 相当于改进版的计数排序,创建桶集合,每个桶存放着对应的数字位数,依次遍历数组序列的每一位,把合适的元素放入桶中,最后二维数组桶中按顺序存放着的就是数组排好序的结果
| void bucket_sort(int* ar, int len) |
| { |
| |
| int** pTemp = new int* [10]; |
| for (int i = 0; i < 10; i++) |
| { |
| |
| pTemp[i] = new int[len]; |
| } |
| int bit_data; |
| int num = 1; |
| int index = 0; |
| while (num < BIGGEST) |
| { |
| |
| for (int i = 0; i < 10; i++) |
| { |
| for (int j = 0; j < len; j++) |
| { |
| pTemp[i][j] = -999; |
| } |
| } |
| |
| |
| for (int i = 0; i < len; i++) |
| { |
| bit_data = ar[i] / num % 10; |
| |
| |
| pTemp[bit_data][i] = ar[i]; |
| } |
| |
| |
| index = 0; |
| for (int i = 0; i < 10; i++) |
| { |
| for (int j = 0; j < len; j++) |
| { |
| if (-999 != pTemp[i][j]) |
| { |
| ar[index++] = pTemp[i][j]; |
| } |
| } |
| } |
| |
| num *= 10; |
| } |
| for (int i = 0; i < len; i++) |
| { |
| |
| delete pTemp[i]; |
| } |
| |
| delete[] pTemp; |
| } |
二分查找
| |
| |
| bool isthisNUM(int* ar, int len,int num) |
| { |
| |
| |
| |
| int left = 0; |
| int right = len - 1; |
| int middle = 0; |
| |
| while (left <= right) |
| { |
| middle = left + (right - left) / 2; |
| if (ar[middle] == num) |
| { |
| return true; |
| } |
| if (num > ar[middle]) |
| { |
| |
| |
| |
| left = middle + 1; |
| } |
| else if (num < ar[middle]) |
| { |
| right = middle - 1; |
| } |
| } |
| return false; |
| } |
| |
| |
| bool isthisNUM_DIGUI(int* ar, int left,int right, int num) |
| { |
| int middle = 0; |
| |
| while (left <= right) |
| { |
| middle = left + (right - left) / 2; |
| if (num > ar[middle]) |
| { |
| return isthisNUM_DIGUI(ar, middle + 1, |
| right, num); |
| } |
| else if (num < ar[middle]) |
| { |
| return isthisNUM_DIGUI(ar, left, middle - 1, |
| num); |
| } |
| else |
| { |
| return true; |
| } |
| } |
| |
| |
| return false; |
| } |
归并排序
- 采用分治的思想,将数组利用递归分成若干个子数组,再排序已经分好的子数组,最后再将子数组合并为一个有序数组
| |
| void Invoking_Func(int* ar, int left, int right) |
| { |
| Split_Arr(ar, left, right); |
| } |
| |
| void Split_Arr(int* ar, int left, int right) |
| { |
| int middle = 0; |
| if (left < right) |
| { |
| middle = left + (right - left) / 2; |
| |
| Split_Arr(ar, left, middle); |
| Split_Arr(ar, middle + 1, right); |
| |
| Merge_Algorithm(ar, left, middle, right); |
| } |
| |
| } |
| |
| void Merge_Algorithm(int* ar, int left, int middle, int right) |
| { |
| int start_left = left; |
| int start_right = middle+1; |
| int pTemp_index = 0; |
| |
| int* pTemp = new int[right - left + 1]; |
| |
| while (start_left <= middle && start_right <= right) |
| { |
| if (ar[start_left] < ar[start_right]) |
| { |
| pTemp[pTemp_index++] = ar[start_left++]; |
| } |
| else |
| { |
| pTemp[pTemp_index++] = ar[start_right++]; |
| } |
| } |
| |
| while (start_left <= middle) |
| { |
| pTemp[pTemp_index++] = ar[start_left++]; |
| } |
| while (start_right <= right) |
| { |
| pTemp[pTemp_index++] = ar[start_right++]; |
| } |
| |
| memcpy(ar + left, pTemp, sizeof(int) * (right - left + 1)); |
| |
| delete[]pTemp; |
| } |
| |
快速排序
- 采用分治的思想,指定一个中间值,将数组分成两块,假设左半区要小于(大于)中间值,否则将此不符合的元素放在右半区,右半区要大于(小于)中间,否则将此不符合的元素放在左半区,下标指针依次移动,最终形成一个有序数组
| |
| void Quick_Func(int* ar, int left, int right) |
| { |
| quickSort(ar, left, right); |
| } |
| |
| void quickSort(int* ar, int left, int right) { |
| |
| |
| |
| if (left >= right) |
| { |
| return; |
| } |
| |
| int start_left = left; |
| int start_right = right; |
| int temp = ar[start_left]; |
| |
| while (start_left < start_right) |
| { |
| while (start_left < start_right && ar[start_right] >= temp) |
| { |
| start_right--; |
| } |
| ar[start_left] = ar[start_right]; |
| while (start_left < start_right && ar[start_left] <= temp) |
| { |
| start_left++; |
| } |
| ar[start_right] = ar[start_left]; |
| } |
| |
| ar[start_left] = temp; |
| |
| |
| |
| quickSort(ar, left, start_left - 1); |
| quickSort(ar, start_left + 1, right); |
| } |
| |
| |
各种排序算法时间比较

| |
| |
| |
| #pragma once |
| #include <cstdlib> |
| #include <ctime> |
| #include <iostream> |
| #include <Windows.h> |
| using namespace std; |
| #define NUM 100000 |
| #define MAX_NUM 100000 |
| |
| |
| int comp1(const void* a, const void* b); |
| |
| class Sort |
| { |
| private: |
| int* ar; |
| int len; |
| time_t time1 = 0; |
| time_t time2 = 0; |
| |
| public: |
| |
| Sort() { len = 0; ar = nullptr; } |
| Sort(int l) |
| { |
| len = l; |
| ar = new int[len]; |
| } |
| Sort(const Sort& s); |
| |
| ~Sort() { delete[] ar; } |
| |
| void InitArr(); |
| |
| void ShowArr(bool fg = false); |
| |
| int Get_max(); |
| |
| void bubble_sort(); |
| |
| void choice_sort(); |
| |
| void insert_sort(); |
| |
| void shell_sort(); |
| |
| void radix_sort(int max); |
| |
| void bucket_sort(); |
| |
| void merge_sort(int left, int right); |
| void Merge_Sort(int left, int middle, int right); |
| |
| void quick_sort(int left, int right); |
| |
| |
| time_t& GetTime1() |
| { |
| return time1; |
| } |
| time_t& GetTime2() |
| { |
| return time2; |
| } |
| |
| time_t GetTime1()const |
| { |
| return time1; |
| } |
| time_t GetTime2()const |
| { |
| return time2; |
| } |
| int* GetArr() |
| { |
| return ar; |
| } |
| |
| |
| Sort& operator=(const Sort& s); |
| }; |
| |
| |
| |
| #include "time.h" |
| |
| Sort::Sort(const Sort& s) |
| { |
| this->len = s.len; |
| this->ar = new int[this->len]; |
| memcpy(this->ar, s.ar, sizeof(int) * this->len); |
| } |
| |
| void Sort::InitArr() |
| { |
| for (int i = 0; i < len; i++) |
| { |
| ar[i] = rand() % MAX_NUM; |
| } |
| } |
| |
| void Sort::ShowArr(bool fg) |
| { |
| if (!fg) |
| { |
| cout << "排序前: \n"; |
| } |
| else |
| { |
| cout << "排序后: \n"; |
| } |
| for (int i = 0; i < len; i++) |
| { |
| cout << ar[i] << " "; |
| } |
| cout << "\n"; |
| } |
| |
| int Sort::Get_max() |
| { |
| int max = ar[0]; |
| for (int i = 0; i < len; i++) |
| { |
| if (max < ar[i]) |
| { |
| max = ar[i]; |
| } |
| } |
| |
| return max; |
| } |
| |
| |
| void Sort::bubble_sort() |
| { |
| int temp; |
| for (int i = 0; i < len - 1; i++) |
| { |
| for (int j = 0; j < len - i - 1; j++) |
| { |
| if (ar[j] > ar[j + 1]) |
| { |
| temp = ar[j]; |
| ar[j] = ar[j + 1]; |
| ar[j + 1] = temp; |
| } |
| } |
| } |
| } |
| |
| |
| void Sort::choice_sort() |
| { |
| int minIdx; |
| int temp; |
| for (int i = 0; i < len - 1; i++) |
| { |
| minIdx = i; |
| for (int j = i + 1; j < len; j++) |
| { |
| minIdx = (ar[minIdx] < ar[j]) ? minIdx : j; |
| } |
| temp = ar[i]; |
| ar[i] = ar[minIdx]; |
| ar[minIdx] = temp; |
| } |
| } |
| |
| void Sort::insert_sort() |
| { |
| int temp; |
| int j; |
| for (int i = 1; i < len; i++) |
| { |
| temp = ar[i]; |
| j = i; |
| while (j && ar[j - 1] >= temp) |
| { |
| ar[j] = ar[j - 1]; |
| j--; |
| } |
| ar[j] = temp; |
| } |
| } |
| |
| void Sort::shell_sort() |
| { |
| |
| int step = len / 2; |
| int temp; |
| int j; |
| while (step) |
| { |
| for (int i = step; i < len; i += step) |
| { |
| temp = ar[i]; |
| j = i; |
| while (j && ar[j - step] >= temp) |
| { |
| ar[j] = ar[j - step]; |
| j -= step; |
| } |
| ar[j] = temp; |
| } |
| |
| step /= 2; |
| } |
| } |
| |
| void Sort::radix_sort(int max) |
| { |
| int p_index = 0; |
| |
| int* pTemp = new int[max + 1]; |
| |
| |
| for (int i = 0; i < max + 1; i++) |
| { |
| pTemp[i] = -999; |
| } |
| |
| |
| for (int i = 0; i < len; i++) |
| { |
| pTemp[ar[i]] = ar[i]; |
| } |
| |
| |
| for (int i = 0; i < max + 1; i++) |
| { |
| if (pTemp[i] != -999) |
| { |
| ar[p_index++] = pTemp[i]; |
| } |
| } |
| delete[] pTemp; |
| } |
| |
| void Sort::bucket_sort() |
| { |
| int num = 1; |
| int bit_data; |
| |
| int** p = new int* [10]; |
| for (int i = 0; i < 10; i++) |
| { |
| p[i] = new int[len]; |
| } |
| |
| #if 1 |
| while (num<MAX_NUM) |
| { |
| |
| for (int i = 0; i < 10; i++) |
| { |
| for (int j = 0; j < len; j++) |
| { |
| p[i][j] = -999; |
| } |
| } |
| |
| |
| for (int i = 0; i < len; i++) |
| { |
| bit_data = ar[i] / num % 10; |
| |
| p[bit_data][i] = ar[i]; |
| } |
| |
| |
| int t_index = 0; |
| for (int i = 0; i < 10; i++) |
| { |
| for (int j = 0; j < len; j++) |
| { |
| if (p[i][j] != -999) |
| { |
| ar[t_index++] = p[i][j]; |
| } |
| } |
| } |
| |
| num *= 10; |
| } |
| #else |
| #endif |
| for (int i = 0; i < 10; i++) |
| { |
| delete[] p[i]; |
| } |
| delete[] p; |
| } |
| |
| void Sort::merge_sort(int left, int right) |
| { |
| int middle = 0; |
| if (left < right) |
| { |
| middle = left + (right - left) / 2; |
| merge_sort(left, middle); |
| merge_sort(middle + 1, right); |
| Merge_Sort(left, middle, right); |
| } |
| } |
| |
| void Sort::Merge_Sort(int left, int middle, int right) |
| { |
| int sL = left; |
| int sR = middle + 1; |
| int t_index = 0; |
| |
| int* pTemp = new int[right - left + 1]; |
| |
| while (sL <= middle && sR <= right) |
| { |
| if (ar[sL] < ar[sR]) |
| { |
| pTemp[t_index++] = ar[sL++]; |
| } |
| else |
| { |
| pTemp[t_index++] = ar[sR++]; |
| } |
| } |
| |
| while (sL <= middle) |
| { |
| pTemp[t_index++] = ar[sL++]; |
| } |
| while (sR <= right) |
| { |
| pTemp[t_index++] = ar[sR++]; |
| } |
| |
| memcpy(ar + left, pTemp, sizeof(int) * (right - left + 1)); |
| |
| delete[] pTemp; |
| } |
| |
| void Sort::quick_sort(int left, int right) |
| { |
| if (left >= right) |
| { |
| return; |
| } |
| |
| int sL = left; |
| int sR = right; |
| int temp = ar[sL]; |
| |
| |
| while (sL < sR) |
| { |
| while (sL < sR && ar[sR] >= temp) |
| { |
| sR--; |
| } |
| ar[sL] = ar[sR]; |
| while (sL < sR && ar[sL] <= temp) |
| { |
| sL++; |
| } |
| ar[sR] = ar[sL]; |
| } |
| ar[sL] = temp; |
| |
| |
| quick_sort(left, sL - 1); |
| quick_sort(sL + 1, right); |
| } |
| |
| Sort& Sort::operator=(const Sort& s) |
| { |
| this->len = s.len; |
| this->ar = new int[this->len]; |
| memcpy(this->ar, s.ar, sizeof(int) * this->len); |
| return *this; |
| } |
| |
| |
| |
| int comp1(const void* a, const void* b) |
| { |
| if (*(int*)a > *(int*)b) |
| { |
| return 1; |
| } |
| else if (*(int*)a < *(int*)b) |
| { |
| return -1; |
| } |
| else |
| { |
| return 0; |
| } |
| } |
| |
| #include "time.h" |
| |
| time_t time1 = 0; |
| time_t time2 = 0; |
| |
| int main() |
| { |
| srand(time(0)); |
| |
| Sort ar1(NUM); |
| ar1.InitArr(); |
| Sort ar2; |
| ar2 = ar1; |
| Sort ar3(ar1); |
| Sort ar4(ar1); |
| Sort ar5; |
| ar5 = ar1; |
| Sort ar6(ar1); |
| Sort ar7(ar1); |
| int* arr_sort = new int[NUM]; |
| memcpy(arr_sort, ar1.GetArr(), sizeof(int) * NUM); |
| |
| cout << "10w 个数据的排序算法比较: \n\n"; |
| #if 1 |
| #if 1 |
| ar1.GetTime1() = GetTickCount(); |
| ar1.bubble_sort(); |
| ar1.GetTime2() = GetTickCount(); |
| cout << "冒泡排序用时: " << ar1.GetTime2() - ar1.GetTime1() |
| << "ms" << endl; |
| |
| |
| ar2.GetTime1() = GetTickCount(); |
| ar2.choice_sort(); |
| ar2.GetTime2() = GetTickCount(); |
| cout << "选择排序用时: " << ar2.GetTime2() - ar2.GetTime1() |
| << "ms" << endl; |
| |
| ar3.GetTime1() = GetTickCount(); |
| ar3.insert_sort(); |
| ar3.GetTime2() = GetTickCount(); |
| cout << "插入排序用时: " << ar3.GetTime2() - ar3.GetTime1() |
| << "ms" << endl; |
| #endif |
| ar4.GetTime1() = GetTickCount(); |
| ar4.shell_sort(); |
| ar4.GetTime2() = GetTickCount(); |
| cout << "希尔排序用时: " << ar4.GetTime2() - ar4.GetTime1() |
| << "ms" << endl; |
| |
| ar5.GetTime1() = GetTickCount(); |
| ar5.bucket_sort(); |
| ar5.GetTime2() = GetTickCount(); |
| cout << "桶排序用时: " << ar5.GetTime2() - ar5.GetTime1() |
| << "ms" << endl; |
| |
| ar6.GetTime1() = GetTickCount(); |
| ar6.merge_sort(0,NUM-1); |
| ar6.GetTime2() = GetTickCount(); |
| cout << "归并排序用时: " << ar6.GetTime2() - ar6.GetTime1() |
| << "ms" << endl; |
| |
| ar7.GetTime1() = GetTickCount(); |
| ar7.quick_sort(0, NUM - 1); |
| ar7.GetTime2() = GetTickCount(); |
| cout << "快速排序用时: " << ar7.GetTime2() - ar7.GetTime1() |
| << "ms" << endl; |
| |
| time1 = GetTickCount(); |
| qsort(arr_sort, NUM, sizeof(int), comp1); |
| time2 = GetTickCount(); |
| cout << "qsort排序用时: " << time2 - time1 |
| << "ms" << endl; |
| cout << "基数排序暂不在讨论范围内" << endl; |
| #endif |
| return 0; |
| } |
| `` |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)