排序笔记

排序笔记

此笔记用来记录排序种类,增加熟练度
十大经å¸æŽ’序算法 概览截图

冒泡排序

思路:每次选择出最大或者最小的“冒泡”至最后位置(也可以最前位置)以达到排序效果。

下面以从小到大排序为例

public void bubble(int [] a){
    int len = a.length;
    for(int i=0;i<len-1;i++){
        for(int j=0;j<len-i-1;j++){
            if(a[j]>a[j+1]){
                int tem = a[j];
                a[j] = a[j+1];
                a[j+1] = tem;
            }
        }
    }
}

i 标记已比较过的个数,j 根据 i 缩小需要比较的范围,同时需要考虑下标越界问题

选择排序

思路:将数组划分为 a 已比较部分 b 未比较部分,每次从未比较部分选出最大/小的数,放到已比较部分的末尾/头部

下面以从小到大为例

public void select(int[] a ){
int len = a.length;
        int minindex ;
        for(int i=0;i<len-1;i++){
            minindex=i;//重置最小值的位置,最后一次比较时,a[i-2]与a[i-1]比较
            for(int j=i+1;j<len;j++){
                if(a[minindex]>a[j])
                    minindex=j;
            }
            int tem = a[i];
            a[i] = a[minindex];
            a[minindex] = tem;

        }
}

插入排序

思路:以从小到大为例,将数组划分为a 已比较部分 b 未比较部分,每次从未比较部分的末尾取出一个数x与a部分从后往前比较,如果x小于a中的数a[i],则a中的数顺次后移,否则插入至a[i]右边

public void insertSort(int[] a){
   	 	int len = a.length;
        int preIndex ,current;
       for(int i=1;i<len;i++){
           preIndex = i-1;
           current = a[i];
           while(preIndex>=0 && a[preIndex]>current){
               a[preIndex+1]=a[preIndex];
               preIndex--;
           }
           a[preIndex+1]=current;
       }
}


希尔排序

思路:是普通插入排序的改良版,分割若干子序列,分别进行插入排序,具体算法描述

  • 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  • 按增量序列个数k,对序列进行k 趟排序;
  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

img

代码实现:

public void shell(int [] arr, int gap){
    int len = arr.length;
    while(gap>0){
        for(int i=gap;i<len;i++){
            int preIndex = i-gap;
            int current = arr[i];
            while(preIndex>=0 && arr[preIndex]>current){
                arr[preIndex+gap]=arr[preIndex];
                preIndex-=gap;
            }
            arr[preIndex+gap]=current;
        }
        gap = (int)Math.floor(gap/2);
        
    }
}

归并排序

思路:将数组不断地分为左右两部分直至最小,排序后再依次合并的过程

img

代码

    public void mergeSort(int[] arr) {
        sort(arr, 0, arr.length-1);
    }
    public void sort(int[] arr, int L, int R){
        if(L==R)
         return ;
        int mid = (L+R)>>1;
        sort(arr, L, mid);
        sort(arr, mid+1, R);
        merge(arr, L, R, mid);
    }
    public void merge(int []arr,int L, int R, int mid){
        int [] tem = new int[R-L+1];
        int p1 = mid+1;
        int p2=L;
        int i=0;
        while(p1<=R && p2<=mid){
            tem[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        while(p2<=mid){
            tem[i++] = arr[p2++];
        }
        while(p1<=R){
            tem[i++] = arr[p1++];
        }
        for(i =0; i<tem.length;i++){
            arr[L+i] = tem[i];//L+i顺次合并
        }
    }

快速排序

思路:选择一个基准位,经过排序,使基准位左边的数都比基准位小,右边的数都比基准位大,然后递归的排出有序序列。

代码:

public void main(int[] arr) {
        arr = quickSort(arr, 0, arr.length-1);
    }
public int[] quickSort(int []arr, int left, int right){
        if(left<right){
            int position = getPosition(arr, left, right);
            quickSort(arr, left, position-1);
            quickSort(arr, position+1, right);
        }
        return arr;
    }
public int getPosition(int []arr, int left, int right){
        int pivot = left;
        int index = pivot+1;
        for(int i=index; i<=right; i++){
            if(arr[i]<arr[pivot]){
                swap(arr, i, index);
                index ++;
            }
        }
        swap(arr, pivot,index-1);
        return index-1;
    }
public void swap(int []arr, int i, int j){
        int tem = arr[i];
        arr[i] = arr[j];
        arr[j] =tem;
    }

堆排序

思路:利用大根堆的性质,每次将最大元素与堆尾元素交换,然后刨除最大元素,将剩余元素重新进行调整,形成新的大根堆,依次操作得出数组的排序结果。其中需要了解的是,堆是完全二叉树,完全二叉树A的左子节点为2A+1,右子节点为2A+2

代码:

 public void HeapSort(int[] arr) {
        int len = arr.length;
        createHeap(arr, len);
        for(int i= arr.length-1;i>0;i--){
            swap(arr, 0, i);
            len--;
            heapify(arr,0,len);//对剩余元素重新调整

        }
    }
public void createHeap(int[] arr,int len){
        for(int i=(int)Math.floor(len/2);i>=0;i--){
            heapify(arr, i, len);
        }
    }
public void heapify(int[] arr, int i, int len){
        int left = i*2+1;
        int right = i*2+2;
        int largeIndex = i;
        if(left<len && arr[left]>arr[largeIndex]){
            largeIndex=left;
        }
        if(right<len && arr[right]>arr[largeIndex]){
            largeIndex=right;
        }
        if(largeIndex!=i){
            swap(arr, i, largeIndex);
            heapify(arr, largeIndex, len);//递归调用,对largeIndex节点后的子树都进行调整
        }
    }
public void swap(int[] arr, int i, int j){
        int tem = arr[i];
        arr[i] = arr[j];
        arr[j] = tem;
    }

计数排序

思路:计数排序假定待排序的数是0-k之间的数,然后构建一个数组bucket,其中bucket[i]存放的是待排序数组中 i 出现的次数,然后再将i根据次数顺次放回至原数组,达到排序的目的

代码:

 public void main(int[] arr) {
        countSort(arr, getMaxValue(arr));
    }
public void countSort(int[] arr, int maxValue){
        int[] bucket = new int[maxValue+1];
        for(int value:arr){
            bucket[value]++;
        }
        int i=0;
        for(int j=0;j<bucket.length;j++){
           while(bucket[j]>0){
               arr[i++]=j;
               bucket[j]--;
           }
        }
    }
public int getMaxValue(int[] arr){
        int maxValue = arr[0];
        for(int value:arr){
            if(value>maxValue)
                maxValue=value;
        }
        return maxValue;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值