排序算法(1)
1.冒泡排序
void bubblesort(int num[],const int len) { if (len <= 1) return; bool sign = false; int i, j, tmp; for ( i = 0; i < len - 1; i++) { sign = false; for ( j = len - 1; j > i; j--) { if (num[j] < num[j - 1]) { sign = true; //本轮循环存在排序操作 tmp = num[j - 1]; num[j - 1] = num[j]; num[j] = tmp; } } if (!sign) break; //本轮循环排序已经结束 } }
最好时间复杂度为O(n),最差和平均时间复杂度均为O(n^2),稳定排序。
2.鸡尾酒排序(可以理解为双向冒泡排序)
void cocktail_sort(int num[], const int len) { if (len <= 1) return; int i, left = 0, right = len - 1, temp; while (left<right) { for (i = left; i < right; i++) { if (num[i]>num[i + 1]) { temp = num[i]; num[i] = num[i + 1]; num[i + 1] = temp; } } right--; for (i = right; i > left; i--) { if (num[i - 1] > num[i]) { temp = num[i - 1]; num[i - 1] = num[i]; num[i] = temp; } } left++; } }
效果基本与冒泡排序接近,对于大量乱序数据,其效率还是呵呵。
3.直接插入排序
void insertsort(int num[],const int len) { if (len <= 1) return; int i, j, temp; for ( i = 1; i < len; i++) { if (num[i] < num[i - 1]) { temp = num[i]; for (j = i - 1; j >= 0 && num[j] > temp; j--) { num[j + 1] = num[j]; } num[j + 1] = temp; } } }
引用自:http://www.cnblogs.com/heyuquan/p/insert-sort.html中解释
设数组为a[0…n]。
- 将原序列分成有序区和无序区。a[0…i-1]为有序区,a[i…n] 为无序区。(i从1开始)
- 从无序区中取出第一个元素,即a[i],在有序区序列中从后向前扫描。
- 如果有序元素大于a[i],将有序元素后移到下一位置。
- 重复步骤3,直到找到小于或者等于a[i]的有序元素,将a[i]插入到该有序元素的下一位置中。
- 重复步骤2~4,直到无序区元素为0
时间复杂度:最好O(n),最差、平均都是O(n)。
4.归并算法(采用递归,办法很棒)
//子区间归并函数 void merge(int num[], const int left, const int mid, const int right) { int n1, n2, i, j, k; int *L = nullptr, *R = nullptr; n1 = mid - left + 1; n2 = right - mid; L = new int[n1]; R = new int[n2]; for ( i = 0; i < n1; i++) L[i] = num[left + i]; for ( i = 0; i < n2; i++) R[i] = num[mid + 1 + i]; i = j = 0; k = left; while (i < n1&&j < n2) { if (L[i] <= R[j]) num[k++] = L[i++]; else num[k++] = R[j++]; } //左数组或者右数组存在剩余元素 //将剩余元素合并至原数组末尾处 for (; i < n1; i++) num[k++] = L[i]; for (; j < n2; j++) num[k++] = L[j]; delete[] L; delete[] R; } //采用递归的方式,划分子区间进行排序,最后对子区间进行归并 void mergesort(int num[],const int left,const int right) { if (left >= right) return; else if (right - left >= 50) { int mid = (left + right) / 2; mergesort(num, left, mid); mergesort(num, mid + 1, right); merge(num, left, mid, right); } else { insertsort(num + left, right - left + 1); } }
此处为归并排序的改进版,即字串的数据较少时,采用直接插入法进行排序。在较大数据量的情况下,提升效果较为明显。
使用该改进方法,归并排序仍然为稳定排序,在处理大数据的时候,若要求为稳定,使用此方法较为不错