排序算法学习体会

来源:互联网 发布:矢量软件 编辑:程序博客网 时间:2024/05/17 04:19

引言

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


算法笔记

堆排序

首先堆是一种重要的数据结构,可以实现“动态”的优先队列,优先队列,是一种根据优先级决定出队的顺序,优先队列在很多情况都有使用,常见的有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;        }    }}

这里写图片描述

可以看到,堆的结构实现了,只要每次调用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
优化·是,设定随机数组随机地一个数字为标定点。


总结

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

原创粉丝点击