排序算法的执行时间是衡量算法好坏的最重要的参数。排序的时间开销可用算法执行中的数据比较次数与数据移动次数来衡量。
1、冒泡排序算法
方法二:
6、堆排序算法
1、冒泡排序算法
void bubbleSort(int a[], int n){
for(int i = 0; i < n - 1; i++){
bool isChange = false;
for(int j = 0; j < n - 1 - i; j++){
if(a[j] > a[j + 1]){
swap(a[j], a[j + 1]);
isChange = true;
}
}
if(!isChange) break;
}
}
2、插入排序算法
void insertSort(int a[], int n){
for(int i = 1; i < n; i++){
for(int j = i; j >= 1; j--){
if(a[j] < a[j - 1]){swap(a[j], a[j - 1]);}
}
}
}
3、希尔排序算法该方法的基本思想:设待排序元素序列有n个元素,首先取一个整数gap < n作为间隔,将全部元素分为gap个子序列,所有距离为gap的元素放在同一个子序列中,在每一个子序列中分别施行直接插入排序。然后缩小间隔gap,例如取gap = gap / 2上取整,重复上述的子序列划分和排序工作。直到最后取gap = 1,将所有元素放在同一个序列中为止。希尔排序是不稳定的排序算法。
void shellSort(int a[], int n){
int gap = n;
do{
gap = gap / 3 + 1;
//插入排序算法
for(int i = gap; i < n; i++){
for(j = i; j > 0; j -= gap){
if(a[j] < a[j - gap]){swap(a[j], a[j - gap]);}
}
}
}while(gap > 1);
}
4、快速排序算法快速排序算法是不稳定的排序算法,在一定情况下退化比较快。
方法一:
int partation(int a[], int left, int right){
int low = left, high = right, piovt = a[left];
while(low < high){
while(low < high && piovt <= a[high]) high--;
a[low] = a[high];
while(low < high && piovt >= a[low]) low++;
a[high] = a[low];
}
a[low] = piovt;
return low;
}
方法二:
int partation(int a[], int left, int right){
int i, j, key = a[left];
i = left;
for(j = left + 1; j <= right; j++){
if(a[j] <= key){
i++;
swap(a[i], a[j]);
}
}
swap(a[i], a[left]); //目标数以最左边的数开始的情况
return i;
}
方法三:
int partation(int a[], int left, int right){
int i, j, key = a[right];
i = left - 1;
for(j = left; j <= right - 1; j++){
if(a[j] <= key){
i++;
swap(a[i], a[j]);
}
}
swap(a[i + 1], a[right]); //目标数以最右边数开始的情况
return i + 1;
}
void quickSort(int a[], int left, int right){
if(left < right){
int pos = partation(a, left, right);
quickSort(a, left, pos);
quickSort(a, pos + 1, right);
}
}
5、归并排序算法
void merge(int a[], int left, int mid, int right){
int n = mid - left + 1; //[left, mid]
int m = right - mid; //[mid + 1, right]
int *ls = new int[n];
int *rs = new int[m];
for(int k = 0; k < n; k++) ls[k] = a[left + k];
for(int k = 0; k < m; k++) rs[k] = a[mid + 1 + k];
int i = n, j = m;
int tmp = left;
while(i > 0 && j > 0){
if(ls[n - i] < rs[m - j]){
a[tmp] = ls[n - i]; i--;
}else{
a[tmp] = rs[m - j]; j--;
}
tmp++;
}
while(i){ a[tmp] = ls[n - i];i--; tmp++; }
while(j){ a[tmp] = rs[m - j];j--; tmp++; }
delete[] ls;
delete[] rs;
}
void mergeSort(int a[], int left, int right){
if(left < right){
int mid = left + (right - left) / 2;
mergeSort(a, left, mid);
mergeSort(a, mid + 1, right);
merge(a, left, mid, right);
}
}
6、堆排序算法
一种不稳定的排序算法
/*
* @brief: 最大化堆调整
* @param: p调整的基准点,n当前堆大小
*/
void maxHeapify(int a[], int p, int n){
int lhs = 2 * p + 1, rhs = 2 * p + 2;
int larger = p;
if(lhs < n && a[p] < a[lhs]){ larger = lhs; }
if(rhs < n && a[larger] < a[rhs]){ larger = rhs; }
if(larger != p){
swap(a[p], a[larger]);
maxHeapify(a, larger, n);
}
}
/*
* @brief: 最大化堆
*/
void buildMaxHeap(int a[], int n){
int p = n / 2 - 1;
for(int i = p; i >=0; i--){
maxHeapify(a, i, n);
}
}
/*
* @brief: 堆排序
*/
void heapSort(int a[], int n){
if(a == NULL) return;
buildMaxHeap(a, n);
for(int i = n - 1; i > 0; i--){
swap(a[0], a[i]);
maxHeapify(a, 0, i);
}
}
7、线性排序算法
计数排序 假设n个输入元素中的每一个都是介于0到k之间的整数,此处k为某个整数。当k = O(n)时,计数排序的运行时间为0(n).计数排序的基本思想就是对每一个输入元素x,确定出小于x的元素个数。有了这一信息,就可以把直接放到它在最终输出数组中的位置上。//b是从0下标开始的
void countingSort(int a[], int b[], int n , int c[], int m){
for(int i = 0; i < m; ++i) c[i] = 0;
for(int i = 0; i < n; ++i) { c[a[i]]++; }
for(int i = 1; i < m; ++i) { c[i] += c[i - 1]; }
for(int i = n - 1; i >= 0; i--){
b[c[a[i]] - 1] = a[i];
c[a[i]]--;
}
}