排序算法

冒泡排序

​ 思路:每一次循环将最大值 / / / 最小值放于向后移动。

public static int[] sort(int[] a){
    for(int i=0;i<a.length-1;i++){
        for(int j=0;j<a.length-1-i;j++){
            if(a[j]>a[j+1]){
                int temp = a[j+1];
                a[j+1] = a[j];
                a[j] = temp;
            }
        }
    }
    return a;
}

插入排序

​ 思路:第 i i i 趟,把第 i i i 个元素放到前 i − 1 i - 1 i1 个有序的序列中 。

public static int[] InsertSort(int[] a){
    for(int i=1;i<a.length;i++){
        int temp = a[i];//处理第i个元素
        int j = i-1;
        for(;j>=0 && a[j]>temp;j--){
            a[j+1] = a[j];//大的元素往后移
        }
        a[j+1] = temp;
    }
    return a;
}

选择排序

​ 思路:第 i i i 趟把从 i   i ~ i  结尾最小的元素找到,放到 i i i 位置。

public static int[] SelectedSort(int[] a){
    for(int i=0;i<a.length;i++){
        int min = i;//存放i+1到最后最小的元素所在的下标
     	for(int j=i+1;j<a.length;j++){
            if(a[j]<a[min])
                min = j;
        }
        int temp = a[i];
        a[i] = a[min];
        a[min] = temp;
    }
    return a;
}

希尔排序

​ 思路:将排序的区间分成若干个有跨度的子区间,对每一个子区间,进行插入排序,跨度不断 / 2 / 2 /2 ,最终当跨度为 1 1 1 的时候,进行一个插入排序。

public static int[] shell(int[] a){
    for(int gap = a.length/2;gap>0;gap/=2){
        //对每一分组进行直接插入排序
        for(int i=gap;i<a.length;i++){
            int j = i;
            while(j-gap>=0 && a[j-gap]>a[j]){//大的往后移动
                int temp = a[j];
                a[j] = a[j-gap];
                a[j-gap] = temp;
                j = j-gap;//下一次继续从分组的前一个位置开始
            }
        }
    }
    return a;
}

计数排序

​ 思路:找出数组中的最大值和最小值,每个数都是在 m i n min min m a x max max 之间,用一个长度为( m a x − m i n + 1 max - min + 1 maxmin+1)的数组 c c c 来存储每一个数出现的次数,然后将数组 c c c 转换为前缀和数组,则 c [ i ] c[ i ] c[i],就表示不大于( i + m i n i+min i+min)的元素的个数,按照 c c c 数组还原排序结果。

public static void countSort(int[] a){
	int[] b = new int[a.length];
    int max = a[0];min = a[0];
    for(int i=0;i<a.length;i++){
        if(a[i]>max) max = a[i];
        if(a[i]<min) min = a[i];
    }
    int dis = max - min + ;
    int[] c = new int[dis];
    for(int i=0;i<a.length;i++)
        c[a[i]-min]++;
    for(int i=1;i<c.length;i++)
        c[i] = c[i] + c[i-1];
    for(int i=a.length-1;i>=0;i--){
        b[c[a[i]-min]-1] = a[i];
        c[a[i]-min]--;
    }
    System.out.println(Arrays.toString(b));
}

归并排序

​ 思路:先把数组从中间分成前后两部分,然后分别对前后两部分进行排序,再将排好序的两部分数据合并在一起

public static void mergeSort(int[] a,int left,int right){//待排序数组,要排序的范围[left,right]
    int mid = (left+right)>>1;
    if(left<right){
        mergeSort(a,left,mid);
        mergeSort(a,mid+1,right);
        merge(a,left,mid,right);
    }
}
public static void merge(int[] a,int left,int mid,int right){
    int[] temp = new int[right-left+1];//临时数组,用来归并
    int i=left,j=mid+1,k=0;//左半段用i指向,右半段用j指向,temp数组用k指向
    while(i<=mid && j<=right){
        if(a[i]<a[j])
            temp[k++] = a[i++];
        else
            temp[k++] = a[j++];   
    }
    while(i<=mid) temp[k++] = a[i++];
    while(j<=right) temp[k++] = a[j++];
    for(int x=0;x<temp.length;x++){
        a[left+x] = temp[x];
    }
}

快速排序

​ 思路:

​ 1.首先设定一个分界值,通过该分界值将数组分成左右两部分。

​ 2.将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于或等于分界值。

​ 3.然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。

​ 4.重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。

public static void quickSort(int[] a,int left,int right){
    if(left>right) return;//区间擦肩而过,无效,不需要进行递归
    int i=left,j=right,temp = a[left];//a[left]作为基准点
    while(i!=j){
        while(a[j]>=a[temp] && j>i)
            j--;//只要a[j]大于基准点继续往前移动j
        if(j>i)
            a[i++] = a[j];
        while(a[i]<=a[temp] && i<j)
            i++;
        if(i<j)
            a[j--] = a[i];
    }
    a[i] = temp;//基准点元素放到最终位置
    quickSort(a,left,i-1);
    quickSort(a,i+1,right);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值