七大排序分类:
插入排序:直接插入排序(稳定) --> 希尔排序(不稳定);
选择排序:简单选择排序(稳定) --> 堆排序(不稳定);
交换排序:冒泡排序(稳定) --> 快速排序(不稳定);
归并排序。
直接插入排序
时间复杂度 : O(n^2)
算法稳定性:稳定
- 算法流程:
1)初始时,a[0]自成一个有序区,无序区为a[1,…,n-1],令i = 1;得到一个新的记录数增1的有序表。
2)将a[i]并入当前的有序区a[0, … ,i-1];
3)i ++,并重复步骤2),直到 i = n - 1,排序完成。
void StraightInsertSort (int []a,int n){
for(int i = 1; i < n; i ++){
for(int j = i - 1;j = 0 && a[j] > a[j + 1]; j --){
Swap(a[j],a[j+1]);
}
}
}
冒泡排序
时间复杂度:O(n^2)
算法稳定性:稳定
1)比较相邻的两个元素,如果前面的数据大于后面的数据,就将两个数据交换;这样对数组第0个元素到第 n-1 个元素进行一次遍历后,最大的一个元素就沉到数组的第 n-1 个位置;
2)重复步骤1)直到 i = n - 1;
void BubbleSort(int []p,int len){
for(int i = 0; i < len; i ++){
for(int j = 0; j < len - i - 1; j ++){
if(p[j] > p[j + 1]){
Swap(p[j] , p[j + 1]);
}
}
}
}
简单选择排序
时间复杂度:O(n^2)
算法稳定性:稳定
- 算法流程
(1)从待排序序列中,找到关键字最小的元素;
(2)如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
(3)从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。
void SelectSort(int []p,int len){
int minIndex;
int i,j;
for(i = 0; i < len; i ++){
minIndex = i;
for(j = i + 1; j < len; j ++){
if(p[minIndex] > p[j]) minIndex = j;
}
if(minIndex != i){
Swap(p[i],p[minIndex]);
}
}
}
希尔排序
时间复杂度:O(nlogn )~O(n^2)
算法稳定性: 不稳定
- 算法流程
1)选择一个增量序列t1,t2,…tk,其中ti > tj, tk = 1;
2)按增量序列个数k,对序列进行k趟排序;
3)每趟排序根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各子序列进行直接插入排序,仅增量因子为1时,整个序列作为一个表来处理,表长度即为整个序列的长度。
void ShellSort(int []p,int len){
int inc,tmp;
int i,j;
for(inc = len/2; i > 0; inc /= 2){
for(i = inc; i < len; i ++){
if(p[i] < p[i - inc]){
tmp = p[i];
for(j = i - inc; j >=0 && p[j] > tmp; j -= inc){
p[j + inc] = p[j];
}
p[j + inc] = tmp;
}
}
}
}
归并排序
时间复杂度:O(nlogn)
算法稳定性:稳定
//将有二个有序数列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while (i <= m)
temp[k++] = a[i++];
while (j <= n)
temp[k++] = a[j++];
for (i = 0; i < k; i++)
a[first + i] = temp[i];
}
void mergesort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
mergesort(a, first, mid, temp); //左边有序
mergesort(a, mid + 1, last, temp); //右边有序
mergearray(a, first, mid, last, temp); //再将二个有序数列合并
}
}
boolean MergeSort(int a[], int n)
{
int []p = new int[n];
if (p == NULL)
return false;
mergesort(a, 0, n - 1, p);
delete[] p;
return true;
}
快速排序
时间复杂度:O(nlogn)~O(n^2)
算法稳定性:不稳定
- 算法流程:
1)分解: A[p … r]被划分为两个子串A[p…q-1]和A[q+1…r]使得被划分的两个子串A[p…q-1]<=A[q]<=A[q+1…r];
2)通过递归调用排序,对子序列A[p…q-1]和A[q+1…r]排序;
3)合并
void QuickSort(int[] list,int low,int high){
if(low < high){
int middle = partition(list,low,high);
QuickSort(list,low,middle - 1);
QuickSort(list,middle + 1,high);
}
}
int partition(int[] list,int low,int high){
int pivot = list[low];
while(low < high){
while(low < high && list[high] >= pivot) high --;
while(low < high && list[low] <= pivot) low ++;
list[high] = list[low];
}
list[low] = pivot;
return low;
}
基数排序
- 算法思路:
1)将所有待比较数值(正整数统一为同样的位数长度,数位较短的数前面补0);
2)然后从最低位开始,依次进行一次排序;
3)这样从最低位排序一直到最高位排序完成以后,数列就有序了
int [] RadixSort(int []nums){
int BASE = 10;
int len = nums.length;
int buffer = new int[len];
int maxValue = nums[0],exp = 1;
for(int i = 1; i < len; i ++){
if(nums[i] > maxValue) maxValue = nums[i];
}
while(maxValue / exp > 0){
int [] bucket = new int [BASE];
for(int i = 0; i < bucket.length; i ++){
bucket[(nums[i] / exp) % BASE] ++;
}
for(int i = 1; i < BASE; i ++){
bucket[i] += bucket[i - 1];
}
for(int i = len - 1; i >= 0; i --){
int index = (nums[i] / exp) % BASE;
buffer[-- bucket[(nums[i] / exp) % BASE]] = nums[i];
}
for(int i = 0; i < len; i ++){
nums[i] = buffer[i];
}
exp *= BASE;
}
return nums;
}