排序是将一组数据按递增或递减的顺序排列。排序算法是一种基本的、常用的算法。虽然排序看似简单,但在实际应用中往往面临一些问题。因为实际应用中的数据量是很大的,所以要根据合适的问题寻找一个高效的排序算法。
排序算法分类
- 1.内部排序若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。内部排序又分为多种方法,可分为4类:插入排序、选择排序、交换排序和合并排序
- 2.外部排序使用内部排序时,所有待处理的数据都已调入到计算机内存中,在排序操作时可直接访问使用。但是,计算机内存的容量是有限的,当对大批量的数据进行排序时,不可能一次将数据全部装入内存,即待排序的数据记录存储在外存中(如硬盘、磁带、闪存等)。这时,可从外存中读取一部分数据到内存中,将内存中的数据进行排序后,再存储到外存中,然后再从外存中读取下一部分数据到内存中,再对内存中的这部分数据进行排序。这样将待排序的数据在内存和外存之间进行多次数据交换,达到排序整个数据的目的,这就是外部排序
注意:外部排序最常用的算法是多路归并排序,即将原文件分解成多个能够一次性装入内存的部分,分别把每一部分调入内存完成排序。然后,对已经排序的子文件进行归并排序。
为了之后进行排序检测方便,先编写一个能随机产生不同整型数的函数
#include<stdlib.h>
int CreateData(int arr[], int n, int min, int max){
int i, j, flag;
srand(time(NULL));
if((max - min + 1) < n)
return 0;
for(i = 0; i < n; i++){
do{
arr[i] = (max - min + 1) * rand() / (RAND_MAX + 1) + min;
flag = 0;
for(j = 0; j < i; j++){
if(arr[i] == arr[j])
flag = 1;
}
}while(flag);
}return 1;
}
这段代码是为了之后的排序提供数据的
快速排序(Quick Sort)法是对冒泡排序的一种改进,但都基于交换排序思想,其基本思想是:通过一遍排序将需要排序的数据划分成两部分,使其中一部分数据比另一部分数据小,然后再分别对这两部分数据继续进行这种排序,按此规则继续,直到每个部分为空或只含一个数时,整个快速排序结束。这是一种分治策略,将大批的数据逐步分解,可使用递归的方法编写程序,使程序更简洁。
快速排序使用分治策略来把待排序数据序列分为两个子序列,具体步骤为:
- (1)设定一个分界值,通过该分界值将数组分成左、右两部分。
- (2)将大于等于分界值的数据集中到数组右边部分,小于分界值的数据集中到数组的左边部分。此时,左边部分中各元素都小于等于分界值,而右边部分中各元素都大于等于分界值。
- (3)左边部分和右边部分的数据独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左、右两部分,同样在左边放置较小值,右边放置较大值。整个数组的右边部分的数据也可以做类似处理。
- (4)重复上述过程,通过递归将左边部分排好序后,再右边部分递归顺序。当左、右两部分各数据排序完成后,整个数组的排序也就完成了。
如果还不懂没关系,接下来换一种方式,图解算法:
因此,基线条件为数组为空或只包含一个元素。在这种情况下,只需原样返回数组——根本就不用排序。
快排Python代码
详细C代码如下:
#include<stdio.h>
#include "9_20Rand.c"
#define ARRAYLEN 10
int Division(int a[], int left, int right){
int base = a[left];
while(left < right){
while(left < right && a[right] > base) /*从右向左比较 */
--right;
a[left] = a[right];
while(left < right && a[left] < base) /*从左向右比较 */
++left;
a[right] = a[left];
}
a[left] = base;
return left;
}
void QuickSort(int a[], int left, int right){
int i, j;
if(left < right){
i = Division(a, left, right);
QuickSort(a, left, i - 1);
QuickSort(a, i + 1, right);
}
}
int main(){
int i, a[ARRAYLEN];
for(i = 0; i < ARRAYLEN; i++){
a[i] = 0;
}
if(!CreateData(a, ARRAYLEN, 1, 100)){
printf("生成随机数不成功!\n");
getch();
return 1;
}
printf("原数据:");
for(i = 0; i < ARRAYLEN; i++)
printf("%5d", a[i]);
printf("\n");
QuickSort(a, 0, ARRAYLEN - 1);
printf("排序后:");
for(i = 0; i < ARRAYLEN; i++)
printf("%5d", a[i]);
printf("\n");
getch();
return 0;
}
我的结果如下(由于是随机生成的,所以大家的结果可能跟我不一样,但是结果都是按升序排列的):
详细C++代码如下:
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
vector<T> quicksort(const vector<T> &arr){
if(arr.size() < 2)
return arr;
//set the pivot in the middle
const T* pivot = &arr.front() + arr.size() / 2 - 1;
vector<T> less; //elements less than the pivot
vector<T> greater; //elements greater than the pivot
for(const T* item = &arr.front(); item <= &arr.back(); item++){
if(item == pivot)
continue;
if(*item <= *pivot)
less.push_back(*item);
else
greater.push_back(*item);
}
vector<T> sorted_less = quicksort(less);
vector<T> sorted_greater = quicksort(greater);
sorted_less.push_back(*pivot);
sorted_less.insert(sorted_less.end(), sorted_greater.begin(), sorted_greater.end());
return sorted_less;
}
int main()
{
vector<int> arr = {69, 60, 38, 82, 99, 15, 8, 94, 30, 42, 35, 40, 63, 1, 49, 66, 93, 83, 20, 32, 87, 6, 78, 17, 2, 61, 91, 25, 7, 4, 97, 31, 23, 67, 95, 47, 55, 92, 37, 59, 73, 81, 74, 41, 39};
vector<int> sorted = quicksort(arr);
for(int num : sorted){
cout << num << " ";
}
cout << endl;
return 0;
}
运行结果如下:
生成随机数的小示例
C++代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
srand((unsigned)time(NULL));
for(int i = 0; i < 10; i++)
{
printf("%d ", rand() % 2); //[0, 1]
}
printf("\n");
for(int i = 0; i < 10; i++)
{
printf("%d ", rand() % 5 + 3);
}
return 0;
}
运行结果(因为是随机的,所以如果你和我的不一样,这很正常):
以下可以生成更大的随机数
#include<bits/stdc++.h>
int main()
{
srand((unsigned)time(NULL));
for(int i = 0; i < 10; i++)
{
printf("%d ", (int)(round(1.0 * rand() / RAND_MAX * 50000 + 10000)));
}
return 0;
}