一、归并排序
对给定的数据,利用递归和分治的技术将数据序列划分为越来越小的半子表;对半子表排序后在利用递归算法将排序好的半子表进行合并
半子表小于一定规模(一般为15)时可以直接用插入排序等算法提高性能(不再递归)。
拆分的时候可以进行多路拆分,称为X路排序
public int[] MergeSort(int[] arr)
{
if(arr.length<2)
return arr; //递归终止条件
int mid = arr.length/2;
int[] left = Arrays.copyOfRange(arr,0,mid);//进行切割
int[] right= Arrays.copyOfRange(arr,mid,arr.length);//进行切割
return merge(MergeSort(left),MergeSort(rigth));//进行递归+合并
}
//合并,类似于差值比较
public int[] merge(int[] left,int[] right)
{
int[] result = new int[left.length+right.length];
for(int index = 0,i = 0,j = 0; index < result.lenght; index++)
{
if(i >= left.length)//左边已取完
result[index] = right[j++];
else if(j >= right.length)//右边已取完
result[index] = left[i++]
//比较算法
else if(left[i]>right[j])
result[index] = right[j++];
else
result[index] = left[i++];
}
return result;
}
二、堆排序
需要处理有序数据,但是不要求全部有序(可能仅需要操作最大的元素),可以使用二叉堆进行排序
二叉堆是一个完全二叉树,同时还满足堆的概念(子节点的value总小于/大于其父节点),对于这种堆,可以称为最大/小堆
由于完全二叉树的特性,可以用一个数组表示其结构(从小到大,且仅有两个结点)
其中最后一个非叶节点为(N/2)-1
思路: ①将最后一个非叶节点和其叶子节点进行比较+交换
②倒序的将非叶节点与其左右孩子进行比较+交换
↑完成完全二叉堆 ↓堆排序
③将堆顶元素和尾元素进行交换
④将尾元素进行脱离,对剩下的二叉树重复①~④
通过此操作可以使堆顶元素(最大/小值)不断剥离
public int[] SortArry(int[] arr)
{
len = arr.length;
if(len<1) return arr;
//构建最大堆
BuildMaxHeap(arr);
//将堆顶元素与末尾元素进行交换并脱出
while( len>0)
{
swap(arr,0,len-1);//交换
len--
AdjustHeap(arr,0);//调整为最大堆
}
}
public int[] BuildMaxHeap(int[] arr)
{
//从最后一个非叶子节点开始向上构造最大堆
for(int i = l(len/2-1); i>-0; i--)
AdjustHeap(arr,i);
}
public void AdjustHeap(int[] arr,int i)
{
int maxIndex = i;
int left = 2*i+1;
int right = 2*(i+1);
//依次比较子树中最大的节点并进行交换
if(left < len && arr[left]>arr[maxIndex])
maxIndex = left;
if(right <len && arr[right]>arr[maxIndex] && arr[right]>arr[left])
maxIndex = right;
if(maxIndex != i)
{
swap(arr,maxIndex,i);
AdjustHeap(arr,maxIndex);
}
}
三、计数排序
计数排序、基数排序、桶排序均利用了桶排序的概念,但是在桶的使用上有差异
计数排序在排序过程中并不比较元素大小,适用于一定范围内(待排序元素较为连续且跨度较小)的整数排序。
步骤: ①初始化一个计数数组(max+1)
②遍历原始数组,将原始数组中的每个元素转换为对应的下标,并将其对应的计数元素+1(例如某数组内有6个值为3的数,则将计数数组下标为3的元素置为6)
③遍历计数数组,若当前计数元素不为0,则将当前原始数组元素置位下标;同事计数元素值-1,原始数组指针+1,循环往复
代码略
四、桶排序
桶排序是计数排序的升级版
工作原理:假设此数据服从均匀分布,将数据分到有限数量的桶里,在从桶中分别排序,排序完成后再合成一个排序后序列
先确立桶的容量,再根据元素的个数确定桶的个数
代码略
五、基数排序
思路:将元素中的所有元素分别按照不同的位数入桶(有几位就入桶几次),每次入桶后形成一个新的序列
代码略