Java排序

7 篇文章 0 订阅

Java排序

1.基础排序

1.1冒泡排序

  • 排序原理

    /*
    * 1.比较相连的元素,如果前一个元素比后一个大的话,就交换两个元素;
    * 2.对每一对相连的元素做同样的操作,从一开始的第一对元素到结尾的最后
    *一对元素,最终的位置就是最大元素。
    */
    
  • 实例

    package com.atrx.algorithm.sort;
    
    public class Bubble {
        //对数组中元素进行排序
        public static void sort(Comparable[] a){
            for (int i=a.length-1;i>0;i--){
                for(int j=0;j<i;j++){
                    //索引j j+1处元素大小
                    if(greater(a[j],a[j+1])){
                        exch(a,j,j+1);
                    }
                }
            }
        }
        //比较v个元素是否大于w元素
        private static boolean greater(Comparable v,Comparable w){
            return  v.compareTo(w)>0;
        }
        //交换数组元素i j的位置
        private static void exch(Comparable[] a,int i,int j){
            Comparable temp;
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    
package com.atrx.algorithm.sort;

import java.util.Arrays;

public class BubbleTest {
    public static void main(String[] args) {
        Integer[] a={4,5,6,3,2,1};
        Bubble.sort(a);
        System.out.println(Arrays.toString(a));
        //[1, 2, 3, 4, 5, 6]
        //时间复杂度为n^2
    }
}

1.2选择排序

  • 排序原理

    /*
    * 1.在每一次遍历过程中,都假定第一个索引处的元素是最小值,和其他元素索引处元素的值进行比较,如果当前索引处的值大于
    * 其他某个索引处的值,则假定其他某个索引处的值为最小值,最后找到最小值所在元素的索引;
    * 2.交换第一个索引处和最小值所在索引处的值;
    * */
    
  • 实例

    package com.atrx.algorithm.sort;
    public class Selection {
        //对数组中元素进行排序
        public static void sort(Comparable[] a){
            for(int i=0;i<a.length-1;i++){
                int minIndex=i;//假定最小元素的索引值为
                for(int j=i+1;j<a.length;j++){
                    //满足,则赋值minIndex=j
                    if(greater(a[minIndex],a[j])){
                        minIndex=j;
                    }
                exch(a,i,minIndex);
                }
            }
        }
        //比较v个元素是否大于w元素
        private static boolean greater(Comparable v,Comparable w){
            return  v.compareTo(w)>0;
        }
        //交换数组元素i j的位置
        private static void exch(Comparable[] a,int i,int j){
            Comparable temp;
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    
    package com.atrx.algorithm.sort;
    
    import java.util.Arrays;
    
    public class SelectionTest {
        public static void main(String[] args) {
            Integer[] a={4,6,8,7,9,2,10,1};
            Selection.sort(a);
            System.out.println(Arrays.toString(a));
            //[1, 2, 4, 6, 7, 8, 9, 10]
            //时间复杂度为n^2
        }
    }
    

1.3 插入排序

  • 排序原理

    /*
    * 1.先把所有元素分为已排好序的和未排好序的;
    * 2.找到未排好序组的第一个元素,向已经排好序的组中插入;
    * 3.倒叙遍历已经排好序的元素,依次和待插入元素进行比较,直到有一个元素小于等于待插入元素,
    * 那么把待插入元素放到这个位置,其他元素向后移动一位。
     */
    
  • 实例

    package com.atrx.algorithm.sort;
    public class Insertion {
        //对数组中元素进行排序
        public static void sort(Comparable[] a){
            for (int i=1;i<a.length;i++){
                for(int j=i;j>0;j--){
                    if(greater(a[j-1],a[j])){
                        exch(a,j-1,j);
                    }else {
                        break;
                    }
                }
            }
        }
        //比较v个元素是否大于w元素
        private static boolean greater(Comparable v,Comparable w){
            return  v.compareTo(w)>0;
        }
        //交换数组元素i j的位置
        private static void exch(Comparable[] a,int i,int j){
            Comparable temp;
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    
package com.atrx.algorithm.sort;

import java.util.Arrays;

public class InsertionTest {
    public static void main(String[] args) {
        Integer[] a={4,3,2,10,12,1,5,6};
        Insertion.sort(a);
        System.out.println(Arrays.toString(a));
        //[1, 2, 3, 4, 5, 6, 10, 12]
        //时间复杂度:n^2
    }
}

2.高级排序

2.1希尔排序

  • 排序原理

    /*
    * 1.选定一个增长量h,按照h对数组数据进行分组;
    * 2.对分好组的每一组数据进行插入排序;
    * 3.减小增长量h,最小减为1,重复第二步操作。
    * */
    
  • 实例

    package com.atrx.algorithm.sort;
    
    public class Shell {
        //对数组中元素进行排序
        public static void sort(Comparable[] a) {
            //根据a的长度,确定增长量h
            int h=1;
            while(h<a.length/2){
                h=h*2+1;
            }
            //希尔排序
            while(h>=1){
                //排序
    
                for(int i=h;i<a.length;i++){
                    //找到待插入的元素
                    for (int j=i;j>=h;j-=h) {
                        //将待插入元素插入到有序数组中
                        if(greater(a[j-h],a[j])){
                            //交换元素
                            exch(a,j-h,j);
                        }else{
                            break;
                        }
                    }
                    }
                //减小h的值
                h=h/2;
            }
        }
        //比较v个元素是否大于w元素
        private static boolean greater(Comparable v,Comparable w){
            return  v.compareTo(w)>0;
        }
        //交换数组元素i j的位置
        private static void exch(Comparable[] a,int i,int j){
            Comparable temp;
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    
package com.atrx.algorithm.sort;

import java.util.Arrays;

public class ShellTest {
    public static void main(String[] args){
        Integer[] a={9,1,2,5,7,4,8,6,3,5};
        Shell.sort(a);
        System.out.println(Arrays.toString(a));
    }
}

2.2归并排序

  • 排序原理

    /*
     * 归并排序原理(分治):
     * 1.尽可能将一组数据分成两个元数个数相等的子组,并对每个子组进行继续拆分,直到拆分后的元素个数唯一;
     * 2.将相连的两个子组进行合并成一个有序的大组;
     * 3.不断地重复步骤2,直到只有一个组为止。
     * */
    
  • 实例

    package com.atrx.algorithm.sort;
    
    public class Merge {
        //对数组中元素进行排序
        public static void sort(Comparable[] a) {
            //初始化数组assist
            assist = new Comparable[a.length];
            //定义一个lo,hi变量,分别记录数组中最小的索引和最大的的索引
            int lo = 0;
            int hi = a.length - 1;
            //调用sort重载方法完成数组中从lo到hi的元素的排序
            sort(a, lo, hi);
        }
    
        //归并需要的辅助数组
        private static Comparable[] assist;
    
        //比较v个元素是否大于w元素
        private static boolean less(Comparable v, Comparable w) {
            return v.compareTo(w) < 0;
        }
    
        //交换数组元素i j的位置
        private static void exch(Comparable[] a, int i, int j) {
            Comparable temp;
            temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    
        //对数组中从lo到hi的元素进行排序
        private static void sort(Comparable[] a, int lo, int hi) {
            //安全校验
            if (hi <= lo) {
                return;
            }
            //对lo到hi之间的数据分为两个组
            int mid = lo + (hi - lo) / 2;
            //分别对每一组数据进行排序
            sort(a, lo, mid);
            sort(a, mid + 1, hi);
            //把两个数组中数据进行归并
            merge(a, lo, mid, hi);
        }
    
        //d对数组中,从lo到mid为一组,从mid+1到hi为一组,对这两组数据进行合并
        private static void merge(Comparable[] a, int lo, int mid, int hi) {
            //定义三个指针
            int i = lo;
            int p1 = lo;
            int p2 = mid+1;
            //遍历,移动p1和p2,比较对应索引处的值,找出最小的,放到辅助数组的对应索引处
            while (p1 <= mid && p2 <= hi) {
                if (less(a[p1], a[p2])) {
                    assist[i++] = a[p1++];
                } else {
                    assist[i++] = a[p2++];
                }
            }
                //遍历,如果p1的指针没有走完,那么顺序移动p1指针,把对应的元素放到辅助数组的对应索引处
                while (p1 <= mid) {
                    assist[i++] = a[p1++];
                }
                //遍历,如果p2的指针没有走完,那么顺序移动p2指针,把对应的元素放到辅助数组的对应索引处
                while (p2 <= hi) {
                    assist[i++] = a[p2++];
                }
                //把辅助数组中的元素拷贝到原数组中
                for (int index = lo; index <= hi; index++) {
                    a[index] = assist[index];
                }
        }
    }
    
package com.atrx.algorithm.sort;

import java.util.Arrays;

public class MergeTest {
    public static void main(String[] args) {
        Integer[] a={8,4,5,7,1,3,6,2};
        Merge.sort(a);
        System.out.println(Arrays.toString(a));
        //[1, 2, 3, 4, 5, 6, 7, 8]
        //时间复杂度:n*log(n)
    }
}

2.3快速排序

  • 排序原理

    /*
    * 1.首先设立一个分界值,通过该分界值将数组分成左右两个部分;
    * 2.将大于等于分界值的数据放到数组右边,小于的放到左边。则此时左边部分各元素小于或等于分界值,
    * 右边部分各元素大于或等于分界值;
    * 3.然后,左右两边的数据可以独立排序。对于左边数据又可以设立一个分界值,将该部分分成左右两
    * 部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似的操作;
    * 4.重复上述过程,很明显这是一个递归过程。通过递归将左侧的排好序后,再递归排好右边部分,当
    * 左右两边排好后,整个数组也就排好序了。
    * */
    
  • 实例

    package com.atrx.algorithm.sort;
    
    public class Quick {
        //对数组中元素进行排序
        public static void sort(Comparable[] a){
            int lo=0;
            int hi=a.length-1;
            sort(a,lo,hi);
        }
        //对数组中索引从lo到hi之间的元素进行排序
        private static void sort(Comparable[] a,int lo,int hi){
            if(hi<=lo){
                return;
            }
            int partition=partition(a,lo,hi);
            sort(a,lo,partition-1);
            sort(a,partition+1,hi);
        }
        //对数组中从索引lo和hi之间的元素进行分组,并返回分组界限对应的索引
        public static int partition(Comparable[] a,int lo,int hi){
            //确定分界值
            Comparable key=a[lo];
            //定义两个指针,分别指向待切分元素的最小索引处和最大索引处的下一个位置
            int left=lo;
            int right=hi+1;
            //切分
            while(true){
                //先从右往左,移动right指针,找到一个比分界值小的元素为止
                while(less(key,a[--right])){
                    if(right==lo){
                        break;
                    }
                }
                //先从左往右,移动left指针,找到一个比分界值大的元素为止
                while(less(a[++left],key)){
                    if(left==hi){
                        break;
                    }
                }
                //判断left>=right,如果成立,这证明元素完成移动,结束循环;如果不是,交换元素即可
                if(left>=right){
                    break;
                }else {
                    exch(a,left,right);
                }
            }
            //交换分界值
            exch(a,lo,right);
            return right;
        }
        //比较v个元素是否大于w元素
        private static boolean less(Comparable v,Comparable w){
            return  v.compareTo(w)<0;
        }
        //交换数组元素i j的位置
        private static void exch(Comparable[] a,int i,int j){
            Comparable temp;
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    
    package com.atrx.algorithm.sort;
    
    import java.util.Arrays;
    
    public class QuickTest {
        public static void main(String[] args) {
            Integer[] a={6,1,2,7,9,3,4,5,8};
            Quick.sort(a);
            System.out.println(Arrays.toString(a));
            //[1, 2, 3, 4, 5, 6, 7, 8, 9]
            //时间复杂度:n
        }
    }
    

2.4堆排序

  • 实例

    package com.atrx.algorithm.sort;
    
    public class HeapSort {
        //判断heap堆中索引i处的元素是否小于j处的元素
        private static boolean less(Comparable[] heap, int i, int j) {
            return heap[i].compareTo(heap[j]) < 0;
        }
    
        //交换heap堆中i与j处索引的值
        private static void exch(Comparable[] heap, int i, int j) {
            Comparable tmp = heap[i];
            heap[i] = heap[j];
            heap[j] = tmp;
        }
    
        //根据原数组source,构造堆heap
        private static void createHeap(Comparable[] source, Comparable[] heap) {
            //source数据拷贝到heap中
            System.arraycopy(source, 0, heap, 1, source.length);
            //对堆中元素做下沉调整
            for (int i = (heap.length) / 2; i > 0; i--) {
                sink(heap, i, heap.length - 1);
            }
        }
    
        //对source数组中的数据进行小到大的排序
        public static void sort(Comparable[] source) {
            //构建堆
            Comparable[] heap = new Comparable[source.length + 1];
            createHeap(source, heap);
            //定义一个变量,记录未排序的元素中最大的索引
            int N = heap.length - 1;
            //通过循环,交换1索引处的元素和排序的元素中的最大索引出的元素
            while (N != 1) {
                //交换元素
                exch(heap, 1, N);
                //排序交换后的最大元素所在的索引,让他不要参与堆的下沉调整
                N--;
                //需要对索引1处的元素做堆的下沉调整
                sink(heap, 1, N);
            }
            //数组的拷贝
            System.arraycopy(heap, 1, source, 0, source.length);
        }
    
        //在heap堆中,对target处的元素做下沉,范围是0~range
        private static void sink(Comparable[] heap, int target, int range) {
            while (2 * target <= range) {
                int max;
                if (2 * target + 1 <= range) {
                    //找出当前节点的较大子节点
                    if (less(heap, 2 * target, 2 * target + 1)) {
                        max = 2 * target + 1;
                    } else {
                        max = 2 * target;
                    }
                } else {
                    max = 2 * target;
                }
                //比较当前节点的值和较大子节点的值
                if (!less(heap, target, max)) {
                    break;
                }
                exch(heap, target, max);
                target = max;
            }
        }
    
    }
    
    package com.atrx.algorithm.sort;
    
    import java.util.Arrays;
    
    public class HeapTest {
        public static void main(String[] args) {
            String[] arr={"s","o","r","t","e","x","a","m","p","l","e"};
            HeapSort.sort(arr);
            System.out.println(Arrays.toString(arr));
            //[a, e, e, l, m, o, p, r, s, t, x]
        }
    }
    

heap, target, max)) {
break;
}
exch(heap, target, max);
target = max;
}
}

}


```java
package com.atrx.algorithm.sort;

import java.util.Arrays;

public class HeapTest {
    public static void main(String[] args) {
        String[] arr={"s","o","r","t","e","x","a","m","p","l","e"};
        HeapSort.sort(arr);
        System.out.println(Arrays.toString(arr));
        //[a, e, e, l, m, o, p, r, s, t, x]
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值