目录
本文里所有代码均为本人原创,若有错误请指正!!!
前言
本人目前为大二学生,算法基础相对薄弱,写此blog来加强自己的算法能力,为ACM等竞赛打好基础。此blog可能有许多错误,还望各位大佬指正!若有志同道合的朋友,可以一起学习算法,共同进步!
提示:以下代码仅供参考!!!
一、插入排序
插入排序,顾名思义,就是在待排序的数组中间插入元素,最终实现排序数组的效果。
1.直接插入
直接插入是最基础的排序方法,其原理为:我们认为前面k个数组是已经排序好的状态,数组中的第k+1个元素,和前面k个元素进行比较,找到他要插入的位置,将后面的元素依次往后移即可。时间复杂度为O(n^2)。(为了方便对比数组大小均为100000(10^5),并且于直接插入算法进行比较)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <algorithm>
using namespace std;
void Print(int* a, int n);
void direct_sort(int* a, int n);
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
int main()
{
srand((unsigned)time(NULL));
int n;
cout << "请输入待排序的数组大小:";
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
direct_sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
sort(num1, num1 + n);
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
排序数组大小为100000是数组(10^5)共用时5727ms。经验证结果正确。
2.折半插入
折半插入就是在直接插入算法的基础上的一个升级,其实我们并不需要去遍历前面的k个元素进行比较,我们只需要和前面数组大小为k的数组的中间值进行比较即可。如果这个数比中间值大,那么就把区间放到都半部分去继续进行比较;否则就在半部分进行比较。最后一定会找到插入的位置,这个查找的时间复杂度就降低到了O(logn)。找到位置后,在继续插入即可。这样这个算法的时间复杂度就是O(nlogn)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <omp.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
void Binary_Sort(int* a, int n);
void Print(int* a, int n);
int find_insert_point(int* a, int n, int l, int r, int i);
void direct_sort(int* a, int n);
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
int find_insert_point(int* a, int n, int l, int r, int i)
{
if (l > r)return l;
int m = (l + r) / 2;
if (a[i] < a[m])return find_insert_point(a, n, l, m - 1, i);
else return find_insert_point(a, n, m + 1, r, i);
}
void Binary_Sort(int* a, int n)
{
for (int i = 1; i < n; i++)
{
int p = find_insert_point(a, n, 0, i - 1, i);
int temp = a[i];
for (int j = i; j > p; j--)
{
a[j] = a[j - 1];
}
a[p] = temp;
}
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
int main()
{
srand((unsigned)time(NULL));
cout << "请输入待排序的数组大小:";
int n;
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Binary_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组需要2845ms。经验证结果正确。
时间上有问题,代码不知道哪里有问题,还望大佬指出!!!
3.希尔排序
希尔排序的原理为:将数组中间隔gap的元素分为一组,并将组内进行排序,然后逐步减小gap,当gap为1时,数组就已经排序好了。这里我们选择的是让gap/=2,来逐步减小gap,这样这个算法的时间复杂度就是O(nlogn^2)或者是O(n^1.3)了。
具体代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;
void Shell_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Shell_Sort(int* a, int n)
{
//Print(a, n,n);
for (int gap = n/2; gap >= 1; gap >>= 1)
{
for (int i = gap; i < n; i++)
{
int temp = a[i];
for (int j = i - gap; j >= 0; j -= gap)
{
if (temp < a[j])Swap(a[j + gap], a[j]);
else break;
}
}
}
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ",a[i]);
//if ((i+1) % gap == 0)cout << endl;
}
cout << endl;
}
int main()
{
srand((unsigned)time(NULL));
int n;
cout << "请输入待排序的数组的大小:";
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Shell_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组仅需要28ms。经验证结果正确。
二、选择排序
选择排序,就是每次都选出这个数组中最大或者最小的元素,这样就可以将数组排序好了。
1.直接选择
直接排序是最直接的排序方式,循环n次,每次都选出数组中第k小的数据,并把它放在数组的第k个位置。时间复杂度为O(n^2)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;
void Choose_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
//if ((i+1) % gap == 0)cout << endl;
}
cout << endl;
}
void Choose_Sort(int* a, int n)
{
for (int i = 0; i < n; i++)
{
int m = a[i];
int dex = i;
for (int j = i + 1; j < n; j++)
{
if (a[j] < m)
{
m = a[j];
dex = j;
}
}
Swap(a[i], a[dex]);
}
}
int main()
{
srand((unsigned)time(NULL));
cout << "请输入待排序的数组的大小:";
int n;
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Choose_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组需要4945ms。经验证结果正确。
2.树形选择
树形选择排序就是利用空间换取时间的思想。将一个数组弄成补成一个2的k次方的数组,多出来的部分用无穷大进行表示。这样我们就可以形成一个完全二叉树,并且每次对比都把2个中最小的一个数,赋值给该节点,这样头节点的数据就是这个数组中最小的数据。然后将这个数据赋值给原数组,并将该数设置为无穷大,进行下一轮迭代。这个算法的时间复杂度为O(nlogn)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
#define M 0x7fffffff
using namespace std;
void Tree_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
cout << endl;
}
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Tree_Sort(int* a, int n)
{
int n1 = n,t = 0;
while (n1)
{
n1 >>= 1;
t++;
}
int n2 = 1;
n2 <<= t;
int n_max = 2 * n2 - 1;
int* num = new int[n_max];
for (int i = 0; i < n2; i++)
{
if (i < n)num[i] = a[i];
else num[i] = M;
}
for (int i = n2; i < n_max; i++)
{
num[i] = min(num[(i - n2) * 2], num[(i - n2) * 2 + 1]);
}
int h = n2;
int pre1 = 0;
for (int i = 0; i < 2 * n2 - 1; i++)
{
cout << num[i] << " ";
if (i+1 == pre1 + h)
{
pre1 += h;
cout << endl;
h >>= 1;
}
}
cout << endl;
a[0] = num[n_max-1];
for (int i = 0; i < n - 1; i++)
{
int temp = num[n_max - 1];
int t = n_max - 1;
while (t >= n2)
{
if (num[(t - n2) * 2] == temp)t = (t - n2) * 2;
else t = (t - n2) * 2 + 1;
}
num[t] = M;
while (t < n_max - 1)
{
num[n2 + t / 2] = min(num[t], num[t ^ 1]);
t = n2 + t / 2;
}
a[i + 1] = num[n_max - 1];
}
delete[]num;
}
int main()
{
srand((unsigned)time(NULL));
cout << "请输入待排序的数组大小:";
int n;
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Tree_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组仅需要29ms,不过需要大量的空间来实现。经验证后结果正确。
三、交换排序
交换排序就是不断的将大的数与小的数交换,将数组进行排序的算法。
1.冒泡排序
冒泡排序就是不断地将大的数和小的数进行交换,大的数放在后面,把最大的数放在数组的末尾。当某一次遍历时若没有发生交换,说明该数组已经排序好了,这时候我们就可以break,跳出循环了。该算法的时间复杂度为O(n^2)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;
void Bubble_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
cout << endl;
}
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Bubble_Sort(int* a, int n)
{
for (int i = 0; i < n; i++)
{
bool over = true;
for (int j = 0; j < n - i - 1; j++)
{
if (a[j] > a[j + 1])
{
Swap(a[j], a[j + 1]);
over = false;
}
}
if (over)break;
}
}
int main()
{
srand((unsigned)time(NULL));
int n;
cout << "请输入待排序的数组的大小:";
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Bubble_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组需要25806ms,时间开销较大。经验证后结果正确。
2.快速排序
快速排序是在数组里面选取一个中间的数作为比较值,将比该值大的元素放在右边,比该元素小的元素放在左边。这样再对这个左右2个数组进行相同的操作,当两个边的边界值相差1时数组就已经排序好了。
这里我们选取3个数进行比较选其中中间值,让中间值尽可能地接近该数组的中位数,来减少递归后的数组的时间复杂度,并且当数组足够小时,可以不需要递归调用,可以选择直接插入的算法进行排序,这样也可以减少时间复杂度。最终时间复杂度为O(nlogn)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;
void Quick_Sort(int* a, int n);
void Quick_Divide(int* a, int left, int right);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int left,int right);
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
cout << endl;
}
void direct_sort(int* a, int left,int right)
{
if (left > right)
{
cout << "Array Error!" << endl;
}
for (int i = left + 1; i <= right; i++)
{
int k = left;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Quick_Divide(int* a, int left, int right)
{
if (right <= left)return;
if (right - left < 10)
{
direct_sort(a, left, right);
return;
}
int num[3] = { a[left],a[right],a[(left + right) / 2] };
sort(num, num+3);
int dex;
if (num[1] == a[left])dex = left;
else if (num[1] == a[right])dex = right;
else dex = (left + right) / 2;
Swap(a[dex], a[left]);
int i = left, j = right;
int temp = a[left];
while (i < j)
{
while (i < j && a[i] < temp)i++;
while (i < j && a[j] >= temp)j--;
Swap(a[i], a[j]);
}
if (a[i] > temp)
{
Quick_Divide(a, left, i - 1);
Quick_Divide(a, i, right);
}
else
{
Quick_Divide(a, left, i);
Quick_Divide(a, i + 1, right);
}
}
void Quick_Sort(int* a, int n)
{
Quick_Divide(a, 0, n - 1);
}
int main()
{
srand((unsigned)time(NULL));
int n;
cout << "请输入待排序的数组的大小:";
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Quick_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, 0, n - 1);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组仅需要14ms。经验证后结果正确。
四、其他排序
1.归并排序
归并排序就是将数组逐步拆分为大小较小的数组,然后逐渐把数组进行合并这样就可以将时间复杂度降低到O(nlogn)了。
注意:这里我们需要把原数组的大小拓展为2的k次方。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;
#define M 0x7fffffff
void Merge_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void Merge(int* a, int n, int hn);
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Merge_Sort(int* a, int n)
{
//Print(a, n);
int t = 0;
int n1 = n;
while (n1)
{
n1 >>= 1;
t++;
}
int n2 = 1;
for (int i = 0; i < t; i++)
{
n2 <<= 1;
}
int* num = new int[n2];
for (int i = 0; i < n; i++)
{
num[i] = a[i];
}
for (int i = n; i < n2; i++)
{
num[i] = M;
}
for (int i = 0; i < n2 / 2; i++)
{
if (num[2 * i] > num[2 * i + 1])Swap(num[2 * i], num[2 * i + 1]);
}
int hn = 2;
while (hn <= n2 / 2)
{
Merge(num, n2, hn);
hn <<= 1;
//Print(num, n);
}
//Print(num, n2);
for (int i = 0; i < n; i++)
{
a[i] = num[i];
}
//Print(a, n);
}
void Merge(int* num, int n, int hn)
{
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num1[i] = num[i];
}
int t = 2 * hn;
for (int i = 0; i < n / t; i++)
{
int start = i * t, end = start + t - 1, k = start, p1 = start, p2 = start + hn;
while (p1 < start + hn && p2<=end)
{
if (num1[p1] <= num[p2])
{
num[k++] = num1[p1++];
//if (k == 1)cout << num[0] << endl;
}
else
{
num[k++] = num1[p2++];
//if (k == 1)cout << num[0] << endl;
}
}
while (p1 < start + hn)num[k++] = num1[p1++];
while (p2 <= end)num[k++] = num1[p2++];
}
delete[]num1;
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ",a[i]);
//if ((i+1) % gap == 0)cout << endl;
}
cout << endl;
}
int main()
{
srand((unsigned)time(NULL));
cout << "请输入待排序的数组的大小:";
int n;
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Merge_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1, n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组仅需要15ms。经验证后结果正确。
2.基数排序
基数排序,就是以某一个进制为基础,将该数组分为若干个数组(几进制就用几个数组),将余数相同的数放在一个数组里,然后将这个数右移一位。这里需要找到,最大的一个数的最高位次,就可以知道需要迭代多少轮了。这样排序后都是按照位次一步一步排序好的,所以最后结果也是对的,不过这个需要大量的空间去存放数据。时间复杂度为O(nlogn)。
具体代码为:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <time.h>
using namespace std;
void Base_Sort(int* a, int n);
void Print(int* a, int n);
void Swap(int& a, int& b);
void direct_sort(int* a, int n);
void Base_Sort_pre(int* a, int n, int loop);
void direct_sort(int* a, int n)
{
if (n <= 1)
{
cout << "Array Error!" << endl;
}
for (int i = 1; i < n; i++)
{
int k = 0;
while (a[i] > a[k])k++;
int temp = a[i];
for (int j = i; j > k; j--)
{
a[j] = a[j - 1];
}
a[k] = temp;
}
}
void Swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void Print(int* a, int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
//if ((i+1) % gap == 0)cout << endl;
}
cout << endl;
}
void Base_Sort_pre(int* a, int n,int loop)
{
//cout << t << endl;
int d[10] = { 1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000 };
int* bucket[10] = { };
int c[10] = { 0 };
for (int j = 0; j < n; j++)
{
c[(a[j] / d[loop]) % 10]++;
}
for (int k = 0; k < 10; k++)
{
bucket[k] = (int*)malloc(c[k] * sizeof(int));
}
for (int m = 0; m < 10; m++)c[m] = 0;
for (int l = 0; l < n; l++)
{
int row = (a[l] / d[loop]) % 10;
bucket[row][c[row]] = a[l];
c[row]++;
}
int s = 0;
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < c[x]; y++)
{
a[s] = bucket[x][y];
s++;
}
}
for (int p = 0; p < 10; p++)
{
free(bucket[p]);
}
}
void Base_Sort(int* a, int n)
{
int ma = 0;
for (int i = 0; i < n; i++)
{
if (a[i] > ma)ma = a[i];
}
int t = 0;
int ai = ma;
//cout << ai << endl;
while (ai)
{
ai /= 10;
t++;
}
for (int i = 0; i < t; i++)
{
Base_Sort_pre(a, n, i);
}
}
int main()
{
srand((unsigned)time(NULL));
cout << "请输入待排序的数组的大小:";
int n;
cin >> n;
int* num = new int[n];
int* num1 = new int[n];
for (int i = 0; i < n; i++)
{
num[i] = rand();
num1[i] = num[i];
}
clock_t start = clock();
Base_Sort(num, n);
clock_t end = clock();
cout << "Sort " << n << " datas use " << (double)(end - start) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
//Print(num, n);
clock_t start1 = clock();
direct_sort(num1,n);
clock_t end1 = clock();
cout << "Sort " << n << " datas use " << (double)(end1 - start1) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
bool equal = true;
for (int i = 0; i < n; i++)
{
if (num[i] != num1[i])
{
equal = false;
break;
}
}
//printf("%d\n", equal);
if (equal)cout << "Right!" << endl;
else cout << "Error!" << endl;
delete[]num;
delete[]num1;
return 0;
}
该算法排序数组大小为100000的数组仅需要13ms。经验证结果正确。
总结
这个9种排序算法的时间快慢为:基数排序>快速排序>归并排序>希尔排序>树形排序>折半插入>直接选择>直接插入>冒泡排序。
其中,空间开销较大的有:基数排序和树形排序。
每个排序算法都有自己的用途,不能单独从时间快慢上判断这个排序算法的好坏!
以上代码为本人自己原创,可能有许多错误和理解不到位的地方,还望各位大佬指正!!!