计数排序
O(n)。是稳定的排序。限制是元素值的范围不能太大,而且比较集中
即对于对象序列 小红(98分),小明(60分),小张(78分),小李(60分)
按分数排序后 小明(60分),小李(60分),小张(78分),小红(98分)
稳定的意思就是相同分数的小明与小李的顺序关系没有发生变化,依然为小明在小李的前面
实现步骤:对序列data[]进行排序
1.初始化count[],answer[]
2.频率统计
3.累加:计算在answer中的位置
4.输出排序后的序列
int[] countSort(int data[]){
int size = data.length;
//频率统计
for(int i = 0 ; i < size ; i ++){
count[data[i]]++;
}
//累加:的方向决定是升序还是降序排序
for(i = 1 ; i < size ; i ++){
count[i] = count[i] + count[i-1];
}
//输出
for(int i = size-1 ; i >= 0 ; i --){
answer[--count[data[i]]] = data[i];
}
}
快速排序
O(lgn)。挖坑填数,分治法
int[] quickSort(int low,int high,int array[]){
if(high>low){
int l = low,h = high,x = array[low];
while(h>l){
while(h>l&&array[h]>=x) h--;
if(h>l) array[l++] = array[h];
while(h>l&&array[l]<=x) l++;
if(h>l) array[h--] = array[l];
}
array[l] = x; //l=h
quickSort(low,high-1,array);
quickSort(low+1,high,array);
}
}
归并排序:
O(lgn)。递归合并,POJ2299(求逆序对)
实现原理:基于合并两个有序序列。实现是将原序列不断二分为两个子序列->极限为两个只包含一个数的序列,这两个就可以看成是两个有序的序列。
合并两个有序序列的方法,以升序为例:从两个序列中各取出一个数,小的留下,再接着比较下两个数,直到一个序列为空,再将剩下的序列内的数全部放入新的序列中。
合并
递归
//递归
void mergeSort(int data[], int low , int high,int temp[]){
if(high>low){
int mid = low+((high-low)>>1);
mergeSort(data,low,mid,temp);
mergeSort(data,mid+1,high,temp);
merge(data,low,mid,high,temp);
}
}
//合并两个有序序列
void merge(int data[],int low , int mid , int high,int temp[]){
int i = low , j = mid+1,count = 0; //注意j一定是从mid+1开始计算,是因为 再上面求解mid时的low+((high-low)>>1)操作,当3/2时会向左偏移等于1而不是等于2
while(i<=mid&&j<=high){
if(data[i]<data[j]){
temp[count++] = data[i++];
}else{
temp[count++] = data[j++];
}
}
while(i<=mid)temp[count++] = data[i++];
while(j<=high)temp[count++] = data[j++];
for (int k = 0; k < count; k++) {
data[low+k] = temp[k];
}
}