数据结构05

排序

选择排序

package p5.排序算法;
//选择排序
import p2.线性结构.ArrayList;

import java.util.Arrays;

public class SelectionSort extends Sort{

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

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

冒泡排序

package p5.排序算法;

import java.util.Arrays;

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

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

插入排序

package p5.排序算法;

import java.util.Arrays;

public class InsertionSort extends Sort{
    public InsertionSort(int[] arr){
       super(arr);
    }
    @Override
    public void sort() {
        for (int i = 1;i < arr.length;i++){
            int e = arr[i];
            int j = 0;
            for (j = i;j > 0 && arr[j - 1] > e;j--){
                arr[j] = arr[j - 1];
            }
            arr[j] = e;
        }
//        System.out.println(Arrays.toString(arr));
    }
}

希尔排序

package p5.排序算法;

import java.util.Arrays;

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;
            }
        }
//        System.out.println(Arrays.toString(arr));
    }
}

归并排序

package p5.排序算法;

public class MergeSort extends Sort{

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

    @Override
    public void sort() {
        mergeSort(0,arr.length - 1);
    }

    private void mergeSort(int L, int R) {
        if (L >= R){
            return;
        }
        int mid = (L + R) / 2;
        mergeSort(L,mid);
        mergeSort(mid + 1,R);

        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;
        int j = mid + 1;
        for (int k = L; k <= R;k++){
            if (i > mid){
                arr[k] = aux[j - L];
                j++;
            }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++;
            }
        }
    }
}

快速排序01

package p5.排序算法;

public class QuickSort01 extends Sort{
    public QuickSort01(int[] arr) {
        super(arr);
    }
    @Override
    public void sort() {
        quickSort(0, arr.length - 1);
    }

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

    private int partition(int L, int R) {
        //优化一下 随机让后面的数字和第一个数字换一下
        //尽量避免极端情况
        swap(L, (int) (Math.random() * (R - L + 1) + L));
        int v = arr[L];

        //arr[l+1 ~ j] < v < arr[j+1 ~ i)
        int j = L;
        for (int i = L + 1; i <= R; i++) {
            if (arr[i] < v) {
                swap(j + 1, i);
                j++;
            }
        }
        swap(L, j);
        return j;
    }
}

快速排序02

package p5.排序算法;

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

    @Override
    public void sort() {
        quickSort(0, arr.length - 1);
    }

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

    private int partition(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;
    }
}

快速排序03

package p5.排序算法;

import java.util.Arrays;

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

    @Override
    public void sort() {
        quickSort(0, arr.length - 1);
    }

    private void quickSort(int L, int R) {
        if (L >= R) {
            return;
        }
        swap(L, (int) (Math.random() * (R - L + 1) + L));
        int v = arr[L];
        int lt = L;
        int gt = R + 1;
        int i = L + 1;
        while (i < gt) {
            if (arr[i] < v) {
                swap(i, lt + 1);
                lt++;
                i++;
            } else if (arr[i] > v) {
                swap(i,gt - 1);
                gt--;
            } else {
                i++;
            }
        }
        swap(L,lt);
        quickSort(L,lt - 1);
        quickSort(gt, R);
    }
}

基数排序

package p5.排序算法;
//基数排序
import p3.链式结构.LinkedList;

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

    @Override
    public void sort() {
        int radix = getRadix();
        LinkedList<Integer>[] list = new LinkedList[10];
        for (int i = 0;i < list.length;i++){
            list[i] = new LinkedList<>();
        }
        for (int r = 1;r <= radix;r++){
            for (int i = 0;i < list.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();
                }
            }
        }
    }

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

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

桶排序

package p5.排序算法;
//桶排序
import p2.线性结构.ArrayList;

import java.util.Comparator;

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

    @Override
    public void sort() {
        //1.找到最大值和最小值
        int max = arr[0];
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        //2.确定桶的个数并创建桶
        int bucketNum = (max - min) / arr.length + 1;
        ArrayList<Integer> list[] = new ArrayList[bucketNum];
        for (int i = 0; i < list.length; i++) {
            list[i] = new ArrayList<>();
        }
        //3.遍历源数据 将数据进行分类处理
        for (int i = 0; i < arr.length; i++) {
            list[(arr[i] - min) / arr.length].add(arr[i]);
        }
        //4.对每一个桶进行排序
        for (int i = 0; i < list.length; i++) {
            list[i].sort(new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return o1 - o2;
                }
            });
//            System.out.println("第" + (i+1) + "个桶:" + list[i].toString());
        }
        //5.将所有桶中的数据依次返回到原数组中即可
        int index = 0;  //原数组的角标
        for (int i = 0; i < list.length; i++) {
            for (int j = 0; j < list[i].size(); j++) {
                arr[index++] = list[i].get(j);
            }
        }
//        System.out.println(Arrays.toString(arr));
    }
}

计数排序

package p5.排序算法;

//计数排序
public class CountingSort extends Sort{
    public CountingSort(int[] arr) {
        super(arr);
    }
    @Override
    public void sort() {
        //1.找最大值和最小值
        int max = arr[0];
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        //2.确定桶的长度 确定 数据->桶角标的转换关系 和 桶角标->数据的转换关系
        //创建桶(桶专门用于统计数据出现的次数)
        int[] counts = new int[max - min + 1];
        // index = num - min
        // num = index + min

        //3.遍历原数组arr 将每个数据出现的次数统计在桶里
        for (int i = 0; i < arr.length; i++) {
            counts[arr[i] - min]++;
        }
        //4.遍历桶 按照从左到右的顺序 将每个数字按照出现的次数 依次回填给arr
        int k = 0;
        for (int index = 0; index < counts.length; index++) {
            for (int count = 0; count < counts[index]; count++) {
                int num = index + min;
                arr[k++] = num;
            }
        }
    }
}

插值查找

package p5.排序算法;
//插值查找
public class InterpolationSearch {
    public static void main(String[] args) {
//        int[] arr = {-12,-10,-6,-2,0,2,6,8,12,14,18,22,25,26,30,33,38,40};
        int[] arr = {-1000,-500,-2,0,50,51,52,54,55,90,1500,4000,8000,10000};
        int key = 55;
        int index = interpolationSearch(arr,0, arr.length - 1,key);
        System.out.println("index:" + index);
        System.out.println(count);
        count = 0;
        index = binarySearch(arr,0,arr.length - 1,key);
        System.out.println("index:" + index);
        System.out.println(count);
    }

    private static int binarySearch(int[] arr, int min, int max, int key) {
        count++;
        if (min > max) {
            return -1;
        }
        int mid = (min + max) / 2;
        if (arr[mid] == key) {
            return mid;
        } else if (key < arr[mid]) {
            return binarySearch(arr,min,mid - 1,key);
        } else {
            return binarySearch(arr,mid + 1,max,key);
        }
    }

    private static int count = 0;
    private static int interpolationSearch(int[] arr, int low, int high, int key) {
        count++;
        if (low > high) {
            return -1;
        }
        int mid = low + (int) (1.0 * (key - arr[low]) / (arr[high] - arr[low]) * (high - low));
        if (mid < low || mid > high) {
            return -1;
        }
        if (arr[mid] == key) {
            return mid;
        } else if (key < arr[mid] ) {
            return interpolationSearch(arr,low,mid - 1,key);
        } else {
            return interpolationSearch(arr,mid + 1, high,key);
        }
    }
}

排序时间比较

大致有序 大致平稳 完全随机
package p5.排序算法;
//大致有序 大致平稳 完全随机
import java.util.Random;

public class ArrayData {

    private int type;
    private Random random = new Random();
    private int[] arr = new int[10000];
    public ArrayData(int type){
        this.type = type;
    }

    public int[] makeData(){
        if (type == 0){
            for (int i = 0;i < arr.length;i++){
                arr[i] = random.nextInt(10000);
            }
        }else if (type == 1){
            for (int i = 0;i < arr.length;i++){
                arr[i] = (i + 1) * 1000 + random.nextInt(200);
            }
        }else {
            for (int i = 0;i < arr.length;i++){
                arr[i] = 5000 + i % 2 == 0 ? random.nextInt(500) : - random.nextInt(500);
            }
        }
        return arr;
    }

}

测试类

package p5.排序算法;

import java.util.Arrays;

public class TestSort {
    public static void main(String[] args) {
//        int[] arr = {3,5,3,1,5,3,7,5,9};
//        SelectionSort selectionSort = new SelectionSort(arr);
//        selectionSort.sort();
//        BubbleSort bubbleSort = new BubbleSort(arr);
//        bubbleSort.sort();
//        InsertionSort insertionSort = new InsertionSort(arr);
//        insertionSort.sort();

        ArrayData data = new ArrayData(0);
        int[] arr = data.makeData();
        text01(arr);
        text02(arr);
        text03(arr);
        text04(arr);
        text05(arr);
        test06(arr);
        test07(arr);
        test08(arr);
        test09(arr);
        test10(arr);
        test11(arr);
    }
    
    private static void test11(int[] arr) {
        CountingSort countingSort = new CountingSort(arr);
        Long start = System.currentTimeMillis();
        countingSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("计数排序:" + (end - start) + "ms");
    }

    private static void test10(int[] arr) {
        BucketSort bucketSort = new BucketSort(arr);
        Long start = System.currentTimeMillis();
        bucketSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("桶排序:" + (end - start) + "ms");
    }

    private static void test09(int[] arr) {
        RadixSort radixSort = new RadixSort(arr);
        Long start = System.currentTimeMillis();
        radixSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("基数排序:" + (end - start) + "ms");
    }

    private static void test08(int[] arr) {
        QuickSort03 quickSort03 = new QuickSort03(arr);
        Long start = System.currentTimeMillis();
        quickSort03.sort();
        Long end = System.currentTimeMillis();
        System.out.println("三路快排:" + (end - start) + "ms");
    }

    private static void test07(int[] arr) {
        QuickSort02 quickSort02 = new QuickSort02(arr);
        Long start = System.currentTimeMillis();
        quickSort02.sort();
        Long end = System.currentTimeMillis();
        System.out.println("双路快排:" + (end - start) + "ms");
    }

    private static void test06(int[] arr) {
        QuickSort01 quickSort01 = new QuickSort01(arr);
        Long start = System.currentTimeMillis();
        quickSort01.sort();
        Long end = System.currentTimeMillis();
        System.out.println("单路快排:" + (end - start) + "ms");
    }

    private static void text05(int[] arr) {
        MergeSort mergeSort = new MergeSort(arr);
        Long start = System.currentTimeMillis();
        mergeSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("归并排序"+ (end - start) + "ms");
    }

    private static void text04(int[] arr) {
        ShellSort shellSort = new ShellSort(arr);
        Long start = System.currentTimeMillis();
        shellSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("希尔排序"+ (end - start) + "ms");
    }

    private static void text03(int[] arr) {
        InsertionSort insertionSort = new InsertionSort(arr);
        Long start = System.currentTimeMillis();
        insertionSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("插入排序"+ (end - start) + "ms");
    }

    private static void text02(int[] arr) {
        BubbleSort bubbleSort = new BubbleSort(arr);
        Long start = System.currentTimeMillis();
        bubbleSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("冒泡排序"+ (end - start) + "ms");
    }

    private static void text01(int[] arr) {
        SelectionSort selectionSort = new SelectionSort(arr);
        Long start = System.currentTimeMillis();
        selectionSort.sort();
        Long end = System.currentTimeMillis();
        System.out.println("选择排序"+ (end - start) + "ms");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值