排序性能测试(JAVA)

生成测试用数据

@Test
public void generatePhoneNum() throws Exception {
    generatePhoneNum(50000);
    generatePhoneNum(100000);
    generatePhoneNum(150000);
    generatePhoneNum(200000);
    generatePhoneNum(250000);
}

public void generatePhoneNum(int count) throws Exception {
    BufferedWriter bw =
            new BufferedWriter(new FileWriter(new File("/Users/xxxxx/Desktop/phone" + count + ".txt")));
    for (int i = 0; i < count; i++) {
        bw.write(eleven());
        if (i != count - 1) {
            bw.newLine();
        }
    }
    bw.close();
}

private Random random = new Random();

private String eleven() {
    StringBuilder sb = new StringBuilder("1");
    for (int i = 0; i < 9; i++) {
        sb.append(random.nextInt(10));
    }
    return sb.toString();
}

由此生成了5个待测试数据样本,分别有50,000100,000150,000200,000250,000int
每个int值长度为10,以1为首(模拟电话号码,但因为int只能装2,147,483,647,所以没使用11位,但又懒得改为long类型,聚焦在对比数据即可)。

时间复杂度为O(n2)的排序

@Test
public void sortTest() throws Exception {
    int count = 50000;
    // sortTest(count, "selection");
    // sortTest(count, "bubble");
    // sortTest(count, "insertion");
}

public void sortTest(int count, String sortType) throws Exception {
    int[] sort = new int[count];
    Scanner scanner = new Scanner(new File("/Users/xxxxx/Desktop/phone" + count + ".txt"));
    int i = 0;
    while (scanner.hasNext()) {
        sort[i] = scanner.nextInt();
        i++;
    }
    long start = System.currentTimeMillis();
    if ("selection".equals(sortType)) {
        selectionSort(sort, count);
    } else if ("bubble".equals(sortType)) {
        bubbleSort(sort, count);
    } else if ("insertion".equals(sortType)) {
        insertionSort(sort, count);
    }
    long stop = System.currentTimeMillis();
    System.out.println("数组长度" + count);
    System.out.println(sortType + "排序耗时" + (stop - start) + "毫秒");
}

//   数组长度    选择排序    冒泡排序    插入排序
//    50,000     1,836      4,862      275
//   100,000     6,726     18,813    1,118
//   150,000    14,806     42,590    2,297
//   200,000    26,529     74,957    4,070
//   250,000    40,677    118,969    6,448

不是平均值,只跑了一遍,主要关注插入排序和其他两个排序相比,真是太优秀了

时间复杂度为O(nlogn)的排序

@Test
public void sortTest() throws Exception {
    int count = 50000;
    // sortTest(count, "selection");
    // sortTest(count, "bubble");
    // sortTest(count, "insertion");
    // sortTest(count, "merge");
    sortTest(count, "quick");
}

public void sortTest(int count, String sortType) throws Exception {
    int[] sort = new int[count];
    Scanner scanner = new Scanner(new File("/Users/xuxuesong/Desktop/phone" + count + ".txt"));
    int i = 0;
    while (scanner.hasNext()) {
        sort[i] = scanner.nextInt();
        i++;
    }
    long start = System.currentTimeMillis();
    if ("selection".equals(sortType)) {
        selectionSort(sort, count);
    } else if ("bubble".equals(sortType)) {
        bubbleSort(sort, count);
    } else if ("insertion".equals(sortType)) {
        insertionSort(sort, count);
    } else if ("merge".equals(sortType)) {
        mergeSort(sort, count);
    } else if ("quick".equals(sortType)) {
        quickSort(sort, count);
    }
    long stop = System.currentTimeMillis();
    System.out.println("数组长度" + count);
    System.out.println(sortType + "排序耗时 " + (stop - start) + " 毫秒");
}

//   数组长度    选择排序    冒泡排序    插入排序   归并排序    快速排序
//    50,000     1,836      4,862      275     1,678      21
//   100,000     6,726     18,813    1,118     3,339      21
//   150,000    14,806     42,590    2,297     8,280      22
//   200,000    26,529     74,957    4,070    12,793      26
//   250,000    40,677    118,969    6,448    13,469      40
// 1,000,000                                 364,153      91
// 5,000,000                                             455

//   数组长度    选择排序    冒泡排序    插入排序   归并排序    快速排序
//     50,000     1,836      4,862      275      20         21
//    100,000     6,726     18,813    1,118      40         21
//    150,000    14,806     42,590    2,297      33         22
//    200,000    26,529     74,957    4,070      56         26
//    250,000    40,677    118,969    6,448      89         40
//  1,000,000                                   175         91
//  5,000,000                                   832        455
// 50,000,000                                 9,151      5,332

快速排序这速度…
测试结果中,归并排序走了个弯路,临时数组之前我是用temp = new int[array.length]来完成的,每次都要找一个连续内存的很大的数组,时间全浪费在这儿了。对不起,归并排序。

时间复杂度为O(n)的排序

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.Random;
import java.util.Scanner;

import org.junit.Test;

public class RadixSortTest {

    public void mergeSort(int[] array, int length) {
        mergeSort(array, 0, length - 1);
    }

    private void mergeSort(int[] array, int left, int right) {
        if (left >= right) {
            return;
        }
        int mid = left + ((right - left) >> 1);
        mergeSort(array, left, mid);
        mergeSort(array, mid + 1, right);
        merge(array, left, mid, right);
    }

    private void merge(int[] array, int left, int mid, int right) {
        int[] temp = new int[right - left + 1];
        int leftPos = left;
        int rightPos = mid + 1;
        int tempPos = 0;
        while (leftPos <= mid && rightPos <= right) {
            if (array[leftPos] <= array[rightPos]) {
                temp[tempPos++] = array[leftPos++];
            } else {
                temp[tempPos++] = array[rightPos++];
            }
        }
        while (leftPos <= mid) {
            temp[tempPos++] = array[leftPos++];
        }
        while (rightPos <= right) {
            temp[tempPos++] = array[rightPos++];
        }
        for (int i = 0; i < temp.length; i++) {
            array[left + i] = temp[i];
        }
    }

    public void quickSort(int[] array, int length) {
        quickSort(array, 0, length - 1);
    }

    public void quickSort(int[] array, int left, int right) {
        if (left >= right) {
            return;
        }
        int partition = partition(array, left, right);
        quickSort(array, left, partition - 1);
        quickSort(array, partition + 1, right);
    }

    public int partition(int[] array, int left, int right) {
        int partitionPos = left;
        int partition = array[right];
        for (int i = left; i < right; i++) {
            if (array[i] <= partition) {
                int temp = array[i];
                array[i] = array[partitionPos];
                array[partitionPos] = temp;

                partitionPos++;
            }
        }

        array[right] = array[partitionPos];
        array[partitionPos] = partition;
        return partitionPos;
    }

    public void radixSort(int[] array, int length) {
        int numLength = (array[0] + "").length();
        for (int i = 0; i < numLength; i++) {
            radixSort(array, length, i);
        }
    }

    private void radixSort(int[] array, int length, int index) {
        int pow = (int) Math.pow(10, index);
        // 求最大值
        int max = array[0] / pow % 10;
        for (int i = 1; i < length; i++) {
            int item = array[i] / pow % 10;
            if (max < item) {
                max = item;
            }
        }

        int[] tempArray = new int[max + 1];
        for (int i = 0; i < array.length; i++) {
            int item = array[i] / pow % 10;
            tempArray[item] = tempArray[item] + 1;
        }

        for (int i = 1; i < tempArray.length; i++) {
            tempArray[i] = tempArray[i] + tempArray[i - 1];
        }

        int[] result = new int[length];
        for (int i = length - 1; i >= 0; i--) {
            int item = array[i] / pow % 10;
            result[tempArray[item] - 1] = array[i];
            tempArray[item] = tempArray[item] - 1;
        }

        for (int i = 0; i < length; i++) {
            array[i] = result[i];
        }

    }

    @Test
    public void generatePhoneNum() throws Exception {
        // generatePhoneNum(100000);
        // generatePhoneNum(200000);
        // generatePhoneNum(500000);
        // generatePhoneNum(1000000);
        // generatePhoneNum(5000000);
        // generatePhoneNum(50000000);
    }

    public void generatePhoneNum(int count) throws Exception {
        BufferedWriter bw =
                new BufferedWriter(new FileWriter(new File("/Users/xuxuesong/Desktop/phone" + count + ".txt")));
        for (int i = 0; i < count; i++) {
            bw.write(eleven());
            if (i != count - 1) {
                bw.newLine();
            }
        }
        bw.close();
    }

    private Random random = new Random();

    private String eleven() {
        StringBuilder sb = new StringBuilder("1");
        for (int i = 0; i < 9; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    @Test
    public void sortTest() throws Exception {
        int count = 500000000;
        // sortTest(count, "merge");
        // sortTest(count, "quick");
        sortTest(count, "radix");
    }

    public void sortTest(int count, String sortType) throws Exception {
        int[] sort = new int[count];
        Scanner scanner = new Scanner(new File("/Users/xuxuesong/Desktop/phone" + count + ".txt"));
        int i = 0;
        while (scanner.hasNext()) {
            sort[i] = scanner.nextInt();
            i++;
        }
        long start = System.currentTimeMillis();
        if ("merge".equals(sortType)) {
            mergeSort(sort, count);
        } else if ("quick".equals(sortType)) {
            quickSort(sort, count);
        } else if ("radix".equals(sortType)) {
            radixSort(sort, count);
        }
        long stop = System.currentTimeMillis();
        System.out.println("数组长度" + count);
        System.out.println(sortType + "排序耗时 " + (stop - start) + " 毫秒");
    }

    //   数组长度      归并排序     快速排序     基数排序
    //    100,000       24          14          43
    //    200,000       45          28          71
    //    500,000      153          89         149
    //  1,000,000      162          95         175
    //  5,000,000      886         491         738
    // 50,000,000   10,570       5,590       8,660
}

不过这个结果,有点儿接受不了
其实基数排序还可以继续优化
而且受限于物理机的配置,数据量只能搞到千万级别,再高玩儿不了了
可以看出,一般情况下,快排就可以很好的解决问题了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值