java-数据结构-排序

1.冒泡排序

图示 :

//冒泡排序
public class BubbleSort extends Sort {
    public BubbleSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        for (int i = 0; i <arr.length ; i++) {
            for (int j = 1; j <arr.length-1 ; j++) {
                if (arr[j]>arr[j+1]){
                    swap(j,j+1);
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

2.选择排序

图示:

//选择排序
public class SelectSort extends Sort {
    public SelectSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        for (int i = 0; i <arr.length-1; i++) {
            int minindex=i;
            for (int j = i+1; j <arr.length ; j++) {
                if (arr[j]<arr[minindex]){
                    minindex=j;
                }
            }
            swap(i,minindex);
    }
        System.out.println(Arrays.toString(arr));
}
}

2.快速排序

2.1单路排序

public class QuickSort extends Sort {

    public QuickSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        sortsort(0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    private void sortsort(int L, int R) {
        if (L>=R){
            return;
        }
        //对数组进行划分,并返回划分后的中点
        int p=partition(L,R)-1;
         sortsort(0,p - 2);
        sortsort(p + 1, R);
    }

    private int partition(int L, int R) {
        int j = R+1;
        int i=L+1;
        int v=L;
        while (i<j){
            if (arr[v]<=arr[i]){
                swap(i,j-1);
                j--;
            }else {
                i++;
            }
        }
        swap(L, j-1);

        return j;

    }
}

2.2双路排序

public class TwoQuickSort extends Sort {
    public TwoQuickSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        onemethod(0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    private void onemethod(int L, int R) {
        if (L >= R) {
            return;
        }
        //中间值
        int p = middlevalue(L, R);
        onemethod(L, p - 1);
        onemethod(p + 1, R);
    }

    private int middlevalue(int L, int R) {
  //避免升序情况,让第一个元素随机和其他位置元素交换
        swap(L, (int) (Math.random() * (R - L + 1) + L));
        int v = arr[L];
        int i = L + 1;
        int j = R;
        while (true) {
            while (i <= R && arr[i] < v) {
                i++;
            }
            while (j >= L + 1 && arr[j] > v) {
                j--;
            }
            if (i > j) {
                break;
            }
            swap(i, j);
            i++;
            j--;
        }
        swap(L, j);
        return j;
    }

2.3三路排序

public class ThreeQuickSort extends Sort {
    public ThreeQuickSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        threequicksort(0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    private void threequicksort(int L, int R) {
        if (L>=R){
            return;
        }
        swap(L, (int) (Math.random() * (R - L + 1) + L));
        int v=arr[L];
        int i=L+1;
        int lt=L;
        int gt=R+1;
        while (i<gt){
            if (v<arr[i]){
                swap(i,gt-1);
                  gt--;
            }else if (v>arr[i]){
                swap(i,lt+1);
                i++;
                lt++;
            }else {
                i++;
            }
        }
        swap(L,lt);
       threequicksort(L,lt-1);
       threequicksort(gt,R);
    }
}

3.插入排序

public class insertSort extends Sort {

    public insertSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        int i = 0;
        while (i <= arr.length-1) {
            int j = i;
            if (i == 0) {
                i++;
            }
            while (j > 0) {
                if (arr[j] < arr[j - 1]) {
                    swap(j, j - 1);
                    j--;
                } else {
                    j--;
                }
            }
            i++;
        }
        System.out.println(Arrays.toString(arr));
    }

4.希尔排序

 如图,如果j-gap所对应值大于j所对应值,则交换值,然后在j指向j-gap,在进行对比,直到j-gap小于0或者j-gap的对应值小于j的对应值,此时i++;这个顺序直到i遍历到数组完,在重新得到gap,是gap/2得到新的,再继续刚所述操作。

//自己写的
public class ShellSort extends Sort {
    public ShellSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        int gap = arr.length / 2;
        int i = gap;
        int j = 0;
        while (true) {
            while (i <= arr.length - 1) {
                j=i;
                if (arr[j - gap] < arr[j]) {
                    i++;

                } else if (arr[j - gap] > arr[j]) {
                    swap(j - gap, j);
                    j=j-gap;
                  while (j-gap>0){
                      if (arr[j-gap]<arr[j]){
                               i++;
                               break;
                      }
                      else if (arr[j-gap]>arr[j]){
                          swap(j-gap,j);
                          j=j-gap;
                      }else {
                          i++;break;
                      }
                  }
                } else {
                    swap(j-gap+1,j);
                    i++;
                }
            }
            gap = gap / 2;
            i = gap;

            if (gap<1){break;}
        }
        System.out.println(Arrays.toString(arr));
    }
}

//正宗写法
public class ShellSort extends Sort{
    public ShellSort(int[] arr){
        super(arr);
    }

    @Override
    public void sort() {
        int len=arr.length;
        for (int gap =len/2; gap >0 ; gap=gap/2) {
            for (int i = gap; i <len ; i++) {
                int e=arr[i];
                int j=i;
                while (j-gap>=0&&arr[j-gap]>e){
                    arr[j]=arr[j-gap];
                    j=j-gap;
                }
                arr[j]=e;
            }
        }
    }
}


5.合并排序

public class MergeSort extends Sort {
    public MergeSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        mergesort(0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    private void mergesort(int l, int r) {
        if (l>=r){
            return;
        }
        int mid=(l+r)/2;
        //递归排序当前层级的右边
        mergesort(l,mid);
        //递归排序当前层级的左边
        mergesort(mid+1,r);
        //左边右边排完,进行合并,
        // 如果左边的最大值小于左边的最小值则不需要合并
        if (arr[mid]>arr[mid+1]){
            merge(l,mid,r);
        }
    }
// 合并操作
    private void merge(int l, int mid, int r) {
        //创建了个新数组,方便比较
        int[] aux=new int[r-l+1];
        //复制数组
        for (int k = l; k <=r ; k++) {
            aux[k-l]=arr[k];
        }
        int i=l,j=mid+1;
        for (int k=l;k<=r;k++){
            //左边完毕
            if (i>mid){
                arr[k]=aux[j-l];
            }else if (j>r){//右边完毕
                arr[k]=aux[i-l];
                i++;
            }else if (aux[i-l]<aux[j-l]){
                arr[k]=aux[i-l];
                i++;
            }else{
                arr[k]=aux[j-l];
                j++;
            }
        }
    }
}

6.桶排序

桶排序顾名思义,就是放几个桶并且桶有范围,然后把数放进去,在桶内进行其他排序。

 

//桶排序
public class bucketSort extends Sort {
    public bucketSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        //1.桶的个数 创建桶
        int max=0,min=0;
        for (int i = 0; i < arr.length ; i++) {
            if (arr[i]>max){
                max=arr[i];
            }
            if (arr[i]<min){
                min=arr[i];
            }
        }
        int bucketnum=(max-min)/ arr.length+1;
        System.out.println(bucketnum+"个桶");
        ArrayList<Integer>[] lists=new ArrayList[bucketnum];
        for (int i = 0; i <bucketnum ; i++) {
            lists[i]=new ArrayList<>();
        }
        //2.分配元素
        for (int i = 0; i <arr.length ; i++) {
            lists[(arr[i]-min)/arr.length].add(arr[i]);
        }
        //3.桶内排序
        for (int i = 0; i < lists.length ; i++) {
            lists[i].sort(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1-o2;
                }
            });
        }
        int index=0;
        for (int i = 0; i < bucketnum ; i++) {
            for (int j = 0; j < lists[i].size(); j++) {
              arr[index++]=lists[i].get(j);
            }
        }
        System.out.println(Arrays.toString(arr));

    }
}

7.基数排序

创建0~9个位桶,每个桶实质相当于一个队列,比如说 , 排序如图

 我们先取个位排序那么应该是下图排列,然后每个桶一次出队

 变成如下顺序

 然后在按十位排序,继续上述操作。那么到底进行多少轮呢,取决于,原数组最大值的位数。

//基数排序
public class radixSort extends Sort {
    public radixSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
        //1.轮数  获取最大执行几次
        int radixnum=radixmax(arr);
        System.out.println("轮数为:"+radixnum);
        //2.创建桶 list所有桶的集合 每一个桶是linkedList(当10个队列用)
        LinkedList<Integer>[] list=new LinkedList[10];
        //每一个桶中有list
        for (int i = 0; i <10 ; i++) {
            list[i]=new LinkedList<>();
        }
        //3.开始 分类-收集
        for (int r = 1; r <=radixnum; r++) {  //轮数
            //分类过程
            for (int i = 0; i < arr.length ; i++) {
               list[getIndex(arr[i],r)].offer(arr[i]);
            }
            //收集 遍历桶
            int index=0;
            //收集过程
            for (int i = 0; i < list.length; i++) {
                while (!list[i].isEmpty()){
                   arr[index++]= list[i].poll();
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }


    private int getIndex(int num, int r) {
        //345
        int count=0;
        for (int i = 1; i <=r ; i++) {
            count=num%10;
            num/=10;
        }
        return count;
    }

    private int radixmax(int[] arr) {
        int max=0;
        for (int i = 0; i < arr.length ; i++) {
            if (arr[i]>max){
                max=arr[i];
            }
        }
        return (max+"").length();
    }
}

8.计数排序

指原数组每个元素出现的次数,然后根据统计的次数排序。

 1.先确定原数组最大值和最小值,根据上图最大值为6,最小值为1

2.创建一个计数数组其长度为max-min+1

3.遍历原数组,计算arr[i](当前元素)-min ,这个计算的是当前元素在计数数组的位置,然后出现一次+1.

 4.然后根据次数依次放入到原数组中,num(原数组的数)=index(计数数组的下标)+min,变成

 

//计数排序
public class countSort extends Sort {
    public countSort(int[] arr) {
        super(arr);
    }

    @Override
    public void sort() {
     //1.创建一个计数数组
        int max=0,min=1;
        for (int i = 0; i <arr.length ; i++) {
            if (arr[i]>max){
                max=arr[i];
            }
            if (arr[i]<min){
                min=arr[i];
            }
        }
        System.out.println("最大值:"+max);
        System.out.println("最小值:"+min);
        int[] countarr=new int[max-min+1];
        System.out.println("计数数组长度:"+countarr.length);
        //2.开始计数
        for (int i = 0; i < arr.length ; i++) {
            countarr[arr[i]-min]++;
        }
        //3.按照计数,开始排序   num=index+min
      int k=0;
        for (int index = 0; index <countarr.length ; index++) {
            for (int count = 0; count <countarr[index] ; count++) {
                int num=index+min;
                arr[k++]=num;
            }

            }

        System.out.println(Arrays.toString(arr));


    }
}

附:排序接口

public abstract  class Sort {
    public int[] arr;
    public Sort(){}
    public  Sort(int[] arr){
        this.arr=new int[arr.length];
        for (int i = 0; i <arr.length ; i++) {
            this.arr[i]=arr[i];
        }
    }
    public abstract void sort();
    public void swap(int i,int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值