引言
昨天晚上没写,所以今天早上一大早就来不上我昨天学习算法的笔记,好记性不如烂笔头,尤其是算法,掌握得不是很熟练的。
第一次实现堆,还是很奇妙的感觉。我要让他变成熟悉的感觉
算法笔记
堆排序
首先堆是一种重要的数据结构,可以实现“动态”的优先队列,优先队列,是一种根据优先级决定出队的顺序,优先队列在很多情况都有使用,常见的有CPU的资源管理,虽然可以说现将优先级排好序,然后第一个出队,但是在CPU的资源管理中,不断会有新的任务到来,而且原有任务的优先级也会发生改变,所以如果使用排序就不太好。堆的出队和入队都是logn的时间复杂度。
实现优先队列的方法有三个
- 排好序的数组,插入时找到正确的位置,输出时直接输出第一个元素
- 未排好序的数组,直接插入到末尾,输出时寻找最大值
- 堆,插入和取出最大值都是logn的级别
堆的实现
难点:shiftUp函数,shiftDown函数
class Heap<Item>{
int count;
int capicitiy;
Item[] data;//从1开始计数
public Heap(int capicity){
this.capicity = capicity;
count = 0;
data = new Item[capicity+1];//
}
public Heap(item[] arr, int n){
count = n;
capicity = n;
data= new Item[capicity +1];
for(int i = 1; i <=n ; i++)
data[i] = arr[i-1];
for(int i = count /2 ; i >=1 ; i--)
{
ShiftDown(i);
}
}
public void Insert(Item data){
count++;
ShiftUp(count);
}
private void ShiftUp(int t){
while(t > 1 && data[t] > data[t/2] )
{
swap(data[t],data[t/2]);
t/=2;
}
}
public Item ExtraBigestOne(){
assert(count>= 1);
Item item = data[1];
data[1] = data[count];
count--;
ShiftDown(1);
return item;
}
private void ShiftDown(int t){
while(2 * t <= count){
int j = t * 2;//左孩子下标
//如果右孩子在且大于左孩子,则下标为右孩子下标
if(j + 1 <= count && data[j] < data[j + 1])
j+=1;
if(data[t] >= data[j]) break;
else {swap(data[t],data[j]);
t = j;
}
}
}
可以看到,堆的结构实现了,只要每次调用ExtraBigestOne函数就可以实现数组的排序过程,算法复杂度为nlogn,上面的需要在申请一个大小为n的数组空间,对于一些情况,对空间不敏感度比较高,则需要原地排序。原理差不多,最大的区别为下标从0开始
public void HeapSort<T>(T[] arr, int n){
for(int i = (count-2)/2; i >= 0 ; i--)
{
ShiftDown(arr,n,i);
}
for(int i = n - 1 ; i > 0 ; i++)
{
swap(a[1],a[n-1]);
ShiftDown(arr,--n,1);
}
}
private void ShiftDown(T[] arr, int count ,int t){
while(t * 2 +1 <= count-1){
int j = t * 2 +1;
if(j+1 <= count -1 && arr[j]<arr[j+1])
j++;
if(arr[t] > arr[j]) break;
else{
swap(arr[t],arr[j]);
t = j;
}
}
}
所有排序算法总结
我的总结
插入排序还是可以的,算法复杂度可以进化到O(n),当数组整体有序时,所以在归并排序中,和快速排序中经常这样做,在left。。right小于多少时直接使用插入排序来优化这两类算法。
并且插入排序中也可以优化,因为交换的时间复杂度大于赋值的复杂度。
归并的排序是优化在,切割的两个数组,有可能左边的最后一个大小直接小于右边的第一个大小,这样就没必要执行Merge操作,已经有序了
快速排序,1。单路快排,2。双路快排3。三路快排,三路快排对于任意的数组的优势比较大,可以无视,但是单路快排遇到基本有序和有大量重复的元素时速度会降低到logn
优化·是,设定随机数组随机地一个数字为标定点。
总结
哈哈,把排序算法的坑给填上了,开心,希望以后也一直能这样不断总结,不断成长。