赞
踩
本文里所有代码均为本人原创,若有错误请指正!!!
本人目前为大二学生,算法基础相对薄弱,写此blog来加强自己的算法能力,为ACM等竞赛打好基础。此blog可能有许多错误,还望各位大佬指正!若有志同道合的朋友,可以一起学习算法,共同进步!
提示:以下代码仅供参考!!!
插入排序,顾名思义,就是在待排序的数组中间插入元素,最终实现排序数组的效果。
直接插入是最基础的排序方法,其原理为:我们认为前面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。经验证结果正确。
折半插入就是在直接插入算法的基础上的一个升级,其实我们并不需要去遍历前面的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。经验证结果正确。
时间上有问题,代码不知道哪里有问题,还望大佬指出!!!
希尔排序的原理为:将数组中间隔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。经验证结果正确。
选择排序,就是每次都选出这个数组中最大或者最小的元素,这样就可以将数组排序好了。
直接排序是最直接的排序方式,循环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的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,不过需要大量的空间来实现。经验证后结果正确。
交换排序就是不断的将大的数与小的数交换,将数组进行排序的算法。
冒泡排序就是不断地将大的数和小的数进行交换,大的数放在后面,把最大的数放在数组的末尾。当某一次遍历时若没有发生交换,说明该数组已经排序好了,这时候我们就可以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个数组进行相同的操作,当两个边的边界值相差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。经验证后结果正确。
归并排序就是将数组逐步拆分为大小较小的数组,然后逐渐把数组进行合并这样就可以将时间复杂度降低到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。经验证后结果正确。
基数排序,就是以某一个进制为基础,将该数组分为若干个数组(几进制就用几个数组),将余数相同的数放在一个数组里,然后将这个数右移一位。这里需要找到,最大的一个数的最高位次,就可以知道需要迭代多少轮了。这样排序后都是按照位次一步一步排序好的,所以最后结果也是对的,不过这个需要大量的空间去存放数据。时间复杂度为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种排序算法的时间快慢为:基数排序>快速排序>归并排序>希尔排序>树形排序>折半插入>直接选择>直接插入>冒泡排序。
其中,空间开销较大的有:基数排序和树形排序。
每个排序算法都有自己的用途,不能单独从时间快慢上判断这个排序算法的好坏!
以上代码为本人自己原创,可能有许多错误和理解不到位的地方,还望各位大佬指正!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。