2017-2018-1 20162316刘诚昊 实验三 查找与排序

20162316刘诚昊 2017-2018-2 《Java程序设计》第三次实验 查找与排序

实验链接:


实验三 查找与排序-1:

实验要求:

  完成教材P302 Searching.Java ,P305 Sorting.java中方法的测试
不少于10个测试用例,提交测试用例设计情况(正常,异常,边界,正序,逆序),用例数据中要包含自己学号的后四位。

实验过程:

  • Searching方法我调用了书上的Contact类,最后增加一个我自己的名字,以学号作为电话号尾号。

  • 正常情况:

  • 异常情况:

  • Sorting方法测试代码:

public class SortingTest extends TestCase {
    Comparable[] num1 = {24, 12, 56, 84, 163, 42, 13, 6, 64, 2316};
    Comparable[] num2 = {24, 12, 56, 84, 163, 42, 13, 6, 64, 2316};
    Sorting sort = new Sorting();
    String result1="",result2 = "";

    public void testSelectionSort() throws Exception {
        //正常情况
        sort.selectionSort(num1);
        for (Comparable element : num1) {
            result1 = result1 + element + " ";
        }
        assertEquals("6 12 13 24 42 56 64 84 163 2316 ", result1);
        //逆序
        sort.selectionSort(num2);
        for (Comparable element : num2) {
            result2 = element + " " + result2;
        }
        assertEquals("2316 163 84 64 56 42 24 13 12 6 ", result2);
    }

    public void testInsertionSort() throws Exception {
        //正常情况
        sort.insertionSort(num1);
        for(Comparable element:num1){
            result1 = result1 + element + " ";
        }
        assertEquals("6 12 13 24 42 56 64 84 163 2316 ",result1);
        //反序
        sort.insertionSort(num2);
        for (Comparable element : num2) {
            result2 = element + " " + result2;
        }
        assertEquals("2316 163 84 64 56 42 24 13 12 6 ", result2);
    }

    public void testBubbleSort() throws Exception {
        //正常情况
        sort.bubbleSort(num1);
        for(Comparable element:num1){
            result1 = result1 + element + " ";
        }
        assertEquals("6 12 13 24 42 56 64 84 163 2316 ",result1);
        //反序
        sort.bubbleSort(num2);
        for (Comparable element : num2) {
            result2 = element + " " + result2;
        }
        assertEquals("2316 163 84 64 56 42 24 13 12 6 ", result2);
    }

    public void testQuickSort() throws Exception {
        //正常情况
        sort.quickSort(num1,0,9);
        for(Comparable element:num1){
            result1 = result1 + element + " ";
        }
        assertEquals("6 12 13 24 42 56 64 84 163 2316 ",result1);
        //反序
        sort.quickSort(num2,0,9);
        for (Comparable element : num2) {
            result2 = element + " " + result2;
        }
        assertEquals("2316 163 84 64 56 42 24 13 12 6 ", result2);
    }

    public void testMergeSort() throws Exception {
        //正常情况"6 12 13 24 42 56 64 84 163 2316 "
        sort.mergeSort(num1,0,9);
        for(Comparable element:num1){
            result1 = result1 + element + " ";
        }
        assertEquals("6 12 13 24 42 56 64 84 163 2316 ",result1);
        //反序
        sort.mergeSort(num2,0,9);
        for (Comparable element : num2) {
            result2 = element + " " + result2;
        }
        assertEquals("2316 163 84 64 56 42 24 13 12 6 ", result2);
    }
}

测试截图:

实验三 查找与排序-1代码链接:

点此返回目录


实验三 查找与排序-2:

实验要求:

  重构你的代码
把Sorting.java Searching.java放入 cn.edu.besti.cs1623.(姓名首字母+四位学号) 包中
把测试代码放test包中
重新编译,运行代码,提交编译,运行的截图(IDEA,命令行两种)

实验过程:

新创文件夹,重构即可:

实验三 查找与排序-2 代码链接:

点此返回目录


实验三 查找与排序-3:

实验要求:

  参考http://www.cnblogs.com/maybe2030/p/4715035.html 在Searching中补充查找算法并测试
提交运行结果截图

实验过程:

    1. 顺序查找与二分查找已在 Searching中给出。
    1. 插值查找

  参考资料:http://blog.csdn.net/xygl2009/article/details/46670069
  与二分查找类似,只是mid不同,后面还是用二分查找的方法:

//插值查找
    //修改自Searching方法中的二分查找
    //key 为目标值
    //n为数组长度
    public static int insertValueSearch (int arr[], int key,  int n)
    {
        int result = -1;
        int high = 0, low = n-1, mid;
        while (result == -1 && high <= low)
        {
            mid = mid=low+(high-low)*(key-arr[low])/(arr[high]-arr[low]); // determine midpoint
            if (arr[mid]==key)
                result = arr[mid];
            else
            if (arr[mid]>key)
                low = mid - 1;
            else
                high = mid + 1;
        }
        return result;
    }
//斐波那契查找
    public static int fibonacciSearch(int[] arr,int key){  //主函数
        //确定需要的斐波那契数
        int i = 0;
        while(getFibonacci(i)-1 == arr.length){
            i++;
        }
        //开始查找
        int low = 0;
        int height = arr.length-1;
        while(low<=height){
            int mid = low + getFibonacci(i-1);
            if(arr[mid] == key){
                return key;
            }else if(arr[mid]>key){
                height = mid-1;
                i--;
            }else if(arr[mid]<key){
                low = mid+1;
                i-=2;
            }
        }

        return -1;
    }

    //得到第n个斐波那契数
    public static int getFibonacci(int n){
        int res = 0;
        if(n == 0){
            res = 0;
        }else if(n == 1){
            res = 1;
        }else{
            int first = 0;
            int second = 1;
            for(int i = 2;i<=n;i++){
                res = first+second;
                first = second;
                second = res;
            }
        }
        return res;
    }
  • 4.树表查找
      树表查找的实现我直接调用了前次实验的LinkedBinarySearchTree来完成:
public static int treeSearch(int[] arr,int key){
        LinkedBinarySearchTree tree = new LinkedBinarySearchTree();
        for(int a = 0; a <arr.length;a++){
            tree.add(arr[a]);
        }
        return (int) tree.find(key);
    }

a. 首先将查找表分成若干块,在每一块中数据元素的存放是任意的,但块与块之间必须是有序的(假设这种排序是按关键字值递增的,也就是说在第一块中任意一个数据元素的关键字都小于第二块中所有数据元素的关键字,第二块中任意一个数据元素的关键字都小于第三块中所有数据元素的关键字,依次类推);
b. 建立一个索引表,把每块中最大的关键字值按块的顺序存放在一个辅助数组中,这个索引表也按升序排列;
c. 查找时先用给定的关键字值在索引表中查找,确定满足条件的数据元素存放在哪个块中,查找方法既可以是折半方法,也可以是顺序查找。
d. 再到相应的块中顺序查找,便可以得到查找的结果。

//分块查找
    //index[]中存放关键值,st为给出的查找数组,m为分成的块数
    //在每一块中数据元素的存放是任意的,但块与块之间必须是有序的(假设这种排序是按关键字值递增的)
    public static int blockSearch(int[] index, int[] st, int key, int m) {
        //检查目标值在哪些块区域范围
        int i = 1;
        boolean t = false;
        while(t = false){
            if (key >= index[i-1])
                i++;
            else
            {
                t = true;
            }
        }
        //在确定的范围中使用顺序查找目标。
        if (i >= 0) {
            int j = i > 0 ? i * m : i;
            int len = (i + 1) * m;
            // 在确定的块中用顺序查找方法查找key
            for (int k = j; k < len; k++) {
                if (key == st[k]) {
                    return key;
                }
            }
        }
        return -1;
    }

测试截图:

代码链接:

supplementSearch

supplementSearchTest

点此返回目录


实验三 查找与排序-4:

实验要求:

补充实现课上讲过的排序方法:希尔排序,堆排序,桶排序,二叉树排序
测试实现的算法(正常,异常,边界)
提交运行结果截图
推送相关代码到码云上

实验过程:

  • 1.希尔排序

  参考资料:https://www.cnblogs.com/LeslieXia/p/5814571.html
  希尔排序是在插入排序的基础上升华,又称缩小增量排序。

//希尔排序
    public static int[] shellSort(int[] arr) {
        // i表示希尔排序中的第n/2+1个元素(或者n/4+1)
        // j表示希尔排序中从0到n/2的元素(n/4)
        // r表示希尔排序中n/2+1或者n/4+1的值
        int i, j, r, tmp;
        for (r = arr.length / 2; r >= 1; r = r / 2) {
            for (i = r; i < arr.length; i++) {
                tmp = arr[i];
                j = i - r;
                // 一轮排序
                while (j >= 0 && tmp < arr[j]) {
                    arr[j + r] = arr[j];
                    j -= r;
                }
                arr[j + r] = tmp;
            }
        }
        return arr;
    }
  • 2.桶排序

  参考资料:http://blog.jobbole.com/100361/    http://flyingcat2013.blog.51cto.com/7061638/1286645/

//桶排序
    public static void bucketSort(int[] arr) {
        int bucketCount =10;
        Integer[][] bucket = new Integer[bucketCount][arr.length];  //Integer初始为null,以与数字0区别。
        for (int i=0; i<arr.length; i++){
            int quotient = arr[i]/10;   //这里即是使用f(x)
            for (int j=0; j<arr.length; j++){
                if (bucket[quotient][j]==null){
                    bucket[quotient][j]=arr[i];
                    break;
                }
            }
        }
        //小桶排序
        for (int i=0; i<bucket.length; i++){
            //insertion sort
            for (int j=1; j<bucket[i].length; ++j){
                if(bucket[i][j]==null){
                    break;
                }
                int value = bucket[i][j];
                int position=j;
                while (position>0 && bucket[i][position-1]>value){
                    bucket[i][position] = bucket[i][position-1];
                    position--;
                }
                bucket[i][position] = value;
            }

        }
        //输出
        for (int i=0, index=0; i<bucket.length; i++){
            for (int j=0; j<bucket[i].length; j++){
                if (bucket[i][j]!=null){
                    arr[index] = bucket[i][j];
                    index++;
                }
                else{
                    break;
                }
            }
        }
    }
  • 3.堆排序

  在此调用第九周的LinkedMaxHeap

 //堆排序
    public static int[] heapSort(int[] arr){
        LinkedMaxHeap heap =new LinkedMaxHeap();
        //将arr中的元素加入堆中
        for(int element: arr){
            heap.add(element);
        }
        //获取堆的根,重新排列arr
        for(int b = 0;b<arr.length;b++){
            arr[b] = (int) heap.getMax();
            heap.removeMax();
        }
        //将arr反向,得到排序结果result
        int a = arr.length;
        int[] result = new int[a];
        for(int b = 0;b<a;b++){
            result[b] = arr[a-b-1];
        }
        return result;
    }
  • 4.二叉树排序

  建立二叉查找树,中序遍历。

//二叉树排序
    public static int[] treeSort(int[] arr){
        LinkedBinarySearchTree tree = new LinkedBinarySearchTree();
        //把元素加入二叉搜索树
        for(int element: arr){
            tree.add(element);
        }
        //创立一个迭代器,将中序遍历出的结果赋给它
        ArrayIterator iter = new ArrayIterator();
        iter = (ArrayIterator) tree.inorder();
        //将迭代器中的元素添加至结果数组
        int result[] = new int[arr.length];
        int b = 0;;
        for(Object element : iter){
            result[b] = (int) element;
            b++;
        }
        return result;
    }

测试截图:

代码链接:

supplementSort
supplementSortTest

点此返回目录

posted @ 2017-11-19 21:53  20162316刘诚昊  阅读(317)  评论(1编辑  收藏  举报