• 20162302 实验三《查找与排序》实验报告


    实 验 报 告

    课程:程序设计与数据结构

    姓名:杨京典

    班级:1623

    学号:20162302

    实验名称:查找与排序

    实验器材:装有IdeaU的联想拯救者15ISK


    实验目的与要求:

    1.完成Searching.JavaSorting.java中方法的测试
    2.重构代码
    3.在Searching中补充查找算法并测试
    4.在Sorting中补充实现课上讲过的排序方法
    5.编写Android程序对各种查找与排序算法进行测试

    实验内容、步骤与体会:

    实验内容:


    完成Searching.JavaSorting.java中方法的测试SeaSorTest

    在测试中要有正常,异常,边界,正序,逆序的情况

    • Searching类里面,有两个查找方法:线性查找linearSearch()和二分查找binarySearch()。其中binarySearch()对于有序数据才有用。所以在建立数据的时候可以专门建立一组有序的数据来供它使用,也可以提前调用Sorting中的方法将数据排序

    构建数据,建立多种类型的数据以测试泛型的实现是否成功

            String[] data1 = {"3", "1", "4", "1", "5", "9", "2", "20162302"};
            Integer[] data2 = {20162302, 2, 5, 8, 95, 3, 6, 5, 2, 6, 7};
            Character[] data3 = {'2', '0', '1', '6', '2', '3', '0', '2', '2', '4'};
            Integer[] data4 = {1, 2, 3, 4, 5, 7, 8, 11, 56, 2302}
    

    测试正常情况,搜索已存在的数据

            System.out.println(searching.linearSearch(data1, "20162302"));
            System.out.println(searching.binarySearch(data4, 20162302));
    

    测试异常情况,搜索不存在的数据

            System.out.println(searching.linearSearch(data2, 34));
            System.out.println(searching.binarySearch(data4, 44));
    

    测试边界情况,搜索首位及末尾数据

            System.out.println(seaching.linearSearch(data1,"3");
            System.out.println(seaching.binarySearch(data4,2302);
            System.out.println(seaching.binarySearch(data4,1);
    
    • Sorting类里面,有五个排序方法选择排序selectionSort,插入排序insertionSort,冒泡排序bubbleSort,快速排序quickSort和归并排序mergeSort。由于每次排序都会对原来的数据造成损坏,所以每次测试都要重新创建数据。(为节省篇幅,这里只举出冒泡排序法的测试)

    测试正常情况

            data1 = {"3", "1", "4", "1", "5", "9", "2", "20162302"};
            sorting.bubbleSort(data1);
    

    测试异常情况,排列只有一个元素的数据以及没有元素的数据

            data1 = {"1"};
            sorting.bubbleSort(data1);
            data1 = {};
            sorting.bubbleSort(data1);
    

    测试边界情况,排列有序数据

            sorting.bubbleSort(data4);
    

    增加方法,测试逆序情况

        public static void diaBubbleSort(Comparable[] data) {
            int position, scan;
    
            for (position = data.length - 1; position >= 0; position--) {
                for (scan = 0; scan <= position - 1; scan++)
                    if (data[scan].compareTo(data[scan + 1]) < 0)
                        swap(data, scan, scan + 1);
            }
        }
    
            data1 =  {"3", "1", "4", "1", "5", "9", "2", "20162302"};
            sorting.diaBubbleSort(data1);
    

    打印排序结果,因为数组是不能直接打印的

    所以要写一个循环来遍历数据

            for (int i = 0; i < data1.length; i++)
                System.out.print(data1[i]+" ");
            System.out.println();
    

    重构代码到包cn.edu.besti.cs1623.yjd2302和包test

    把Sorting.java Searching.java放入cn.edu.besti.cs1623.(姓名首字母+四位学号) 包中,把测试代码放test包中,重新编译,运行代码。对于重构,有两种方法可以做到

    • 第一种方法是在IDEA里面实现的
      首先在项目里面找到src点击右键打开快捷菜单选择new→package

      然后输入包的名称

      然后找到需要移动的代码,点击右键打开快捷菜单选择Refactor→Move

      最后在To package里面输入新建的包

    • 第二种方法可以脱离IDEA
      打开项目的src,直接在里面创建文件夹cn

      打开cn创建edu

      以此类推创建一系列文件夹

      然后把代码复制或剪切进来

      最后把最前面的包名改成刚刚创建的

    Searching中补充查找算法并测试

    参考七大查找算法Searching中补充查找算法并测试

    • 插值算法。帖子里面给出的源码都是c++的
    int InsertionSearch(int a[], int value, int low, int high)
    {
        int mid = low+(value-a[low])/(a[high]-a[low])*(high-low);
        if(a[mid]==value)
            return mid;
        if(a[mid]>value)
            return InsertionSearch(a, value, low, mid-1);
        if(a[mid]<value)
            return InsertionSearch(a, value, mid+1, high);
    }
    

    但是在c++里面有很多和java是相同的,这个里面只应用到了简单的符号运算以及if判断,所以在java里面也可以直接使用,使其变成public即可

        public int insertionSearch(int a[], int value, int low, int high) {
            int mid = low + (value - a[low]) / (a[high] - a[low]) * (high - low);
            if (a[mid] == value)
                return mid;
            if (a[mid] > value)
                return insertionSearch(a, value, low, mid - 1);
            if (a[mid] < value)
                return insertionSearch(a, value, mid + 1, high);
            else
                return 0;
        }
    
    • 斐波那契查找

    基本思想:也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。
      相对于折半查找,一般将待比较的key值与第mid=(low+high)/2位置的元素比较,比较结果分三种情况:
      1)相等,mid位置的元素即为所求
      2)>,low=mid+1;
    3)<,high=mid-1。
      斐波那契查找与折半查找很相似,他是根据斐波那契序列的特点对有序表进行分割的。他要求开始表中记录的个数为某个斐波那契数小1,及n=F(k)-1;
    开始将k值与第F(k-1)位置的记录进行比较(及mid=low+F(k-1)-1),比较结果也分为三种
      1)相等,mid位置的元素即为所求
      2)>,low=mid+1,k-=2;
      说明:low=mid+1说明待查找的元素在[mid+1,high]范围内,k-=2 说明范围[mid+1,high]内的元素个数为n-(F(k-1))= Fk-1-F(k-1)=Fk-F(k-1)-1=F(k-2)-1个,所以可以递归的应用斐波那契查找。
      3)<,high=mid-1,k-=1。
      说明:low=mid+1说明待查找的元素在[low,mid-1]范围内,k-=1 说明范围[low,mid-1]内的元素个数为F(k-1)-1个,所以可以递归 的应用斐波那契查找。

    我将构建斐波那契数组的方法合并到查找方法里面

            int[] F = new int[max_size];
            F[0] = 1;
            F[1] = 1;
            for (int i = 2; i < max_size; ++i)
                F[i] = F[i - 1] + F[i - 2];
            //构造一个斐波那契数组F
    

    在java中为了达到复制数组中的数据的目的

            Integer[] temp = new Integer[F[k] - 1];//将数组a扩展到F[k]-1的长度
            for (int i = 0; i < a.length; i++)
                temp[i] = a[i];
    
    • 树表查找

    基本思想:二叉查找树是先对待查找的数据进行生成树,确保树的左分支的值小于右分支的值,然后在就行和每个节点的父节点比较大小,查找最适合的范围。 这个算法的查找效率很高,但是如果使用这种查找方法要首先创建树。

    在之前的学习中已经有完成的二叉查找树的代码,可以在这里直接调用。

        public int binarySearchTree(int[] data, int a){
            LinkedBinarySearchTree binarySearchTree = new LinkedBinarySearchTree();
            for (int i = 0; i < data.length; i++)
                binarySearchTree.add(data[i]);
            if(binarySearchTree.find(a)==null)
                return -1;
            else
                return a;
        }
    
    • 哈希查找

    算法思想:哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。这是对于简单的键的情况,我们将其扩展到可以处理更加复杂的类型的键。

    建立一个哈希表,然后把数据放进去,以数字为键,查找时检索整个哈希表

        public int hashSearch(int[] data, int a){
            boolean result = false;
            HashMap<Integer, Integer> hashMap = new HashMap();
            for(int i = 0; i<data.length; i++)
                hashMap.put(i,data[i]);
            for(int i = 0; i<data.length; i++)
                if (data[i]==a)
                    result = true;
            if(result)
                return a;
            else
                return -1;
        }
    }
    

    Sorting中补充实现课上讲过的排序方法

    补充实现课上讲过的排序方法:希尔排序,堆排序,桶排序,二叉树排序等。

    • 希尔排序,先取一个小于n的整数d1作为第一个 增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行 直接插入排序;然后,取第二个增量d2。
        //希尔排序
        public void shellSort(Comparable[] data) {
            int d = data.length;
            while (d!=1) {
                d = d / 2;
                for (int i = 0; i < d; i++) {
                    for (int j = i + d; j < data.length; j = j + d) {
                        Comparable temp = data[j];
                        int x;
                        for (x = j - d; x >= 0 && data[x].compareTo(temp) > 0; x = x - d)
                            data[x + d] = data[x];
                        data[x + d] = temp;
                    }
                }
            }
        }
    
    • 堆排序,可以运用堆顶部元素总是为最大元素的特性来获取最大值
        //堆排序
        public void heapSort(Comparable[] data){
            Comparable[] result = data;
            LinkedMaxHeap linkedMaxHeap = new LinkedMaxHeap();
            for (int i = 0; i < result.length; i++)
                linkedMaxHeap.add(result[i]);
            for (int i = result.length-1; i>=0;i--)
                data[i]=linkedMaxHeap.removeMax();
        }
    
    • 桶排序
      参考资料:计数排序和桶排序(Java实现)
      根据数据的范围对这些范围进行分成几个大桶,然后再逐一给大桶里面的数据排序。代码中大致的思路体现出来了,就是不能支持泛型,所以就要对这一部分进行优化。在Comparable中的Compureto()是对两个元素进行比较,并返回差距值,可以理解为做差,这样就可以获取最小值和最大值。
        //桶排序
        public void bucketSort(Comparable[] data){
            Comparable max = data[0];
            Comparable min = data[0];
            for(int i = 0; i < data.length; i++){
                if(max.compareTo(data[i])<0)
                    max = data[i];
                if (min.compareTo(data[i])>0)
                    min = data[i];
            }
            //桶数
            int bucketNum = (max.compareTo(min)) / data.length + 1;
            ArrayList<ArrayList<Comparable>> bucketArr = new ArrayList<>(bucketNum);
            for(int i = 0; i < bucketNum; i++){
                bucketArr.add(new ArrayList<Comparable>());
            }
            //将每个元素放入桶
            for(int i = 0; i < data.length; i++){
                int num = (data[i].compareTo(min)) / (data.length);
                bucketArr.get(num).add(data[i]);
            }
            //对每个桶进行排序
            for(int i = 0; i < bucketArr.size(); i++)
                Collections.sort(bucketArr.get(i));
            int x =0;
            for (int i =0; i<bucketNum;i++)
                for (int j = 0; j<bucketArr.get(i).size();j++) {
                    data[x] = bucketArr.get(i).get(j);
                    x++;
                }
        }
    
    • 二叉树排序,把数据放到树里面,获取最小值然后删除最小值,然后再获取最小值。
        //二叉树排序
        public void binaryTreeSort(Comparable[] data){
            LinkedBinarySearchTree linkedBinarySearchTree = new LinkedBinarySearchTree();
            for (int i = 0; i < data.length; i++)
                linkedBinarySearchTree.add(data[i]);
            for (int i = 0; i < data.length; i++) {
                data[i] = linkedBinarySearchTree.findMin();
                linkedBinarySearchTree.remove(linkedBinarySearchTree.findMin());
            }
        }
    
    • 测试方法
    public class TestF {
        public static void main(String[] args) {
            int[] data1 = {2302, 2, 5, 8, 95, 3, 6, 5, 2, 6, 7};
            Integer[] data2 = {2, 2, 3, 5, 5, 6, 6, 7, 8, 95, 2302};
            Searching searching = new Searching();
            System.out.println(searching.insertionSearch(data1,8,2,0));
            System.out.println(searching.FibonacciSearch(data2,95));
            System.out.println(searching.binarySearchTree(data1, 2302));
            System.out.println(searching.hashSearch(data1, 6));
        }
    }
    public class TestS {
        public static void main(String[] args) {
            Integer[] data1 = {2302, 2, 5, 8, 95, 3, 6, 5, 2, 6, 7};
            Sorting sorting = new Sorting();
            sorting.shellSort(data1);
            for (int i = 0; i < data1.length; i++)
                System.out.print(data1[i]+" ");
            System.out.println();
            Integer[] data2 = {2302, 2, 5, 8, 95, 3, 6, 5, 2, 6, 7};
            sorting.heapSort(data2);
            for (int i = 0; i < data1.length; i++)
                System.out.print(data2[i]+" ");
            System.out.println();
            Integer[] data3 = {2302, 2, 5, 8, 95, 3, 6, 5, 2, 6, 7};
            sorting.bucketSort(data3);
            for (int i = 0; i < data3.length; i++)
                System.out.print(data3[i]+" ");
            System.out.println();
            Integer[] data4 = {2302, 2, 5, 8, 95, 3, 6, 5, 2, 6, 7};
            sorting.binaryTreeSort(data4);
            for (int i = 0; i < data4.length; i++)
                System.out.print(data4[i]+" ");
        }
    }
    

    编写Android程序对各种查找与排序算法进行测试

    设计思路:一共三个界面,第一个界面读入数据并添加数据(后来发现这步可以合并到后面),然后进入到搜索或者排序界面


    • 可以直接在按下跳转按钮的时候传送数据
            Button button1 = (Button) findViewById(R.id.search);
            button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String data = editText.getText().toString();
                    Intent intent = new Intent(MainActivity.this, Search.class);
                    intent.putExtra("extra_data", data);
                    startActivity(intent);
                }
            });
    
    • 对于SearchSort界面大量的按钮可以通过Switch来统一管理
        public void onClick(View v) {
            switch (v.getId()) {
                case:
                    break;
            }
    
  • 相关阅读:
    SwiftUI Github App 源码 All In One
    React Design Patterns All In One
    centos6.9 install samba
    【Nginx】配置文件
    C#实现连接池
    LINUX安装nginx详细步骤
    C#之ref参数和out参数的区别
    【Nginx】反向代理、动静分离、负载均衡、Rewrite、防盗链
    python之requests库
    python \r和\n
  • 原文地址:https://www.cnblogs.com/yangjingdian/p/7820161.html
Copyright © 2020-2023  润新知