排序算法学习体会

引言

昨天晚上没写,所以今天早上一大早就来不上我昨天学习算法的笔记,好记性不如烂笔头,尤其是算法,掌握得不是很熟练的。
第一次实现堆,还是很奇妙的感觉。我要让他变成熟悉的感觉


算法笔记

堆排序

首先堆是一种重要的数据结构,可以实现“动态”的优先队列,优先队列,是一种根据优先级决定出队的顺序,优先队列在很多情况都有使用,常见的有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+=1if(data[t] >= data[j]) break;
        else {swap(data[t],data[j]);
            t = j;
        }
    }

}

排序算法学习体会_第1张图片

可以看到,堆的结构实现了,只要每次调用ExtraBigestOne函数就可以实现数组的排序过程,算法复杂度为nlogn,上面的需要在申请一个大小为n的数组空间,对于一些情况,对空间不敏感度比较高,则需要原地排序。原理差不多,最大的区别为下标从0开始
排序算法学习体会_第2张图片

排序算法学习体会_第3张图片


public void HeapSort(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]1])
            j++;
        if(arr[t] > arr[j]) break;
        else{
            swap(arr[t],arr[j]);
            t = j;
        }
    }


}

所有排序算法总结

排序算法学习体会_第4张图片

我的总结
插入排序还是可以的,算法复杂度可以进化到O(n),当数组整体有序时,所以在归并排序中,和快速排序中经常这样做,在left。。right小于多少时直接使用插入排序来优化这两类算法。
并且插入排序中也可以优化,因为交换的时间复杂度大于赋值的复杂度。
归并的排序是优化在,切割的两个数组,有可能左边的最后一个大小直接小于右边的第一个大小,这样就没必要执行Merge操作,已经有序了
快速排序,1。单路快排,2。双路快排3。三路快排,三路快排对于任意的数组的优势比较大,可以无视,但是单路快排遇到基本有序和有大量重复的元素时速度会降低到logn
优化·是,设定随机数组随机地一个数字为标定点。


总结

哈哈,把排序算法的坑给填上了,开心,希望以后也一直能这样不断总结,不断成长。

你可能感兴趣的:(算法学习)