zoukankan      html  css  js  c++  java
  • 实验三 查找和排序 实验报告 20162305

    实验三 查找和排序 实验报告 20162305

    一、查找和排序-1

    1、实验要求

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

    2、实验过程

    • 这个实验是在教材上的代码基础上实现的。教材中给了Searching类和Sorting类,测试这两个代码中给出的方法。查找类中包含了线性查找和二分查找两种方法。排序类中包含了像选择排序,插入排序,冒泡排序等等方法。这些方法在之前的学习中已经了解过,设计测试类,在两个类的测试类中一一实现这些方法。

    3、实验成果截图

    二、查找和排序-2

    1、实验要求

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

    2、实验过程

    • 按照实验要求,我在IDEA中新建了一个package包,命名为cn.edu.besti.cs162305.lyx。在IDEA中重构代码,将代码加入相应的文件夹中,然后运行,在IDEA中可以实现。不过打开命令行后编译成功后,命令行中显示代码编译没问题,不过结果却没能显示出来。

    3、实验成果截图

    • 命令行

    • IDEA

    • 1、

    • 2、

    三、查找和排序-3

    1、实验要求

    • 参考 查找算法博客 在Searching中补充查找算法并测试
      提交运行结果截图

    2、实验过程

    • 在这篇学习博客中,一共提到了7种查找的方法,分别是顺序查找、二分查找、插值查找、斐波那契查找、树表查找、分块查找和哈希查找。其中的顺序查找和二分查找在教材的代码中都已经实现,下面介绍其他五种查找方法
    (1)、插值查找
    • 插值查找是基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。

    • 插值查找在实际使用时,一般要满足两个假设条件:
      (1)每一次对数据的访问与通常的指令相比,费用都是相当昂贵的。例如,待查找的表一定是在磁盘而非内存中,因而每一次比较都
      要进行磁盘访问。
      (2)数据不仅是已被排好序的,而且呈现均匀分布特征。

    • 实验代码

    
    public static Comparable InsertionSearch(int[] num, int key) {
            //定义三个判断数
            int low, high, mid;
            low = 0;
            high = num.length - 1;
            while (low <= high) {
                // mid = (low + high) / 2;
                //二分查找
                mid = low + (high - low) * (key - num[low]) / (num[high] - num[low]); // 插值查找
                if (key < num[mid]) high = mid - 1;
                else if (key > num[mid]) low = mid + 1;
                else
                    // 如果等于则直接还回下标值
                    return mid;
            }
            return -1;
        }
    
    
    (2)、斐波那契查找
    • 斐波那契查找也是二分查找的一种提升算法,通过运用黄金比例的概念在数列中选择查找点进行查找,提高查找效率。同样地,斐波那契查找也属于一种有序查找算法。
        

    • 相对于折半查找,一般将待比较的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;
      3、high=mid-1,k-=1。

    • 说明: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个,所以可以递归的应用斐波那契查找。

    • 实验代码

    
     private int max_size = 20;//斐波那契数组的长度
    
        /*构造一个斐波那契数组*/
        public void Fibonacci(int[] F) {
            F[0] = 0;
            F[1] = 1;
            for (int i = 2; i < max_size; ++i)
                F[i] = F[i - 1] + F[i - 2];
        }
    
        /*定义斐波那契查找法*/
        int FibonacciSearch(int[] a, int key)  //a为要查找的数组,n为要查找的数组长度,key为要查找的关键字
        {
            int low = 0;
            int high = a.length - 1;
    
            int[] F = new int[max_size];
            Fibonacci(F);//构造一个斐波那契数组F
    
            int k = 0;
            while (a.length > F[k] - 1)//计算n位于斐波那契数列的位置
                ++k;
            //将数组a扩展到F[k]-1的长度
    
            int[] temp = new int[F[k] - 1];
            
            for (int i = 0; i < a.length; i++)
                temp[i] = a[i];
    
    
            for (int i = a.length; i < F[k] - 1; ++i)
                temp[i] = a[a.length - 1];
    
            while (low <= high) {
                int mid = low + F[k - 1] - 1;
                if (key < temp[mid]) {
                    high = mid - 1;
                    k -= 1;
                } else if (key > temp[mid]) {
                    low = mid + 1;
                    k -= 2;
                } else {
                    if (mid < a.length) return mid; //若相等则说明mid即为查找到的位置
                    else return a.length - 1; //若mid>=n则说明是扩展的数值,返回n-1
                }
            }
    
            return 0;
        }
    
    
    (3)、二叉树查找
    • 实现这个方法相对简单。我们可以利用之前实现过的二叉查找树来实现查找功能。定义一个二叉查找树,遍历整个数,利用二叉查找树中的find方法来查找目标值,从而实现查找功能。
    • 实验代码
    
     public int BinaryTreeSearch(int[] a, int key) {
            LinkedBinarySearchTree linkedBinarySearchTree = new LinkedBinarySearchTree();
            //添加元素进入查找树
            for (int i = 0; i < a.length; i++)
                linkedBinarySearchTree.add(a[i]);
            //利用find方法查找值
            if (linkedBinarySearchTree.find(key) == null) return Integer.parseInt(null);
            else return key;
    
        }
    
    
    (4)、分块查找
    • 分块查找又称索引顺序查找,它是顺序查找的一种改进方法。将n个数据元素"按块有序"划分为m块(m ≤ n)。每一块中的结点不必有序,但块与块之间必须"按块有序";即第1块中任一元素的关键字都必须小于第2块中任一元素的关键字;而第2块中任一元素又都必须小于第3块中的任一元素,以此类推。

    • 实验代码

    
    public static int blockSearch(int[] index, int[] a, int key, int m) {  
        // 在序列a数组中,用分块查找方法查找关键字为key的记录  
        // 1.在index[ ] 中折半查找,确定要查找的key属于哪个块中  
        int i = binarySearch(index, key);  
        if (i >= 0) {  
            int j = i > 0 ? i * m : i;  
            int length = (i + 1) * m;  
            // 在确定的块中用顺序查找方法查找key  
            for (int k = j; k < length; k++) {  
                if (key == a[k]) {  
                    System.out.println("查询成功");  
                    return k;  
                }  
            }  
        }  
      
        return -1;  
    }  
    
    
    (5)、哈希查找
    • 利用Java中的HashMap类实现查找功能。其实现过程和二叉查找树实现查找类似。利用HashMap中的put方法将元素添加入表中,再用containKey方法判断有无目标元素,从而实现查找功能。
    • 实验代码
    
        public int HashSearch(int[] a , int key){
            HashMap<Integer,Integer> hashMap = new HashMap();
            for(int i = 0;i <a.length;i++)
                hashMap.put(i,a[i]);
            if(hashMap.containsKey(key) == true)
                return key;
            else
                return 0;
        }
    
    

    3、实验成果截图

    四、查找和排序-4

    1、实验要求

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

    2、实验过程

    (1)、希尔排序
    • 希尔排序的思想是先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量 =1( < …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
    • 实验代码
    
     public static void shellSort(int[] data) {
            int j = 0;
            int temp = 0;
            for (int a = data.length / 2; a > 0; a /= 2) {
                for (int i = a; i < data.length; i++) {
                    temp = data[i];
                    for (j = i - a; j >= 0; j -= a) {
                        if (temp < data[j]) {
                            data[j + a] = data[j];
                        } else {
                            break;
                        }
                    }
                    data[j + a] = temp;
                }
                for (int i = 0; i < data.length; i++)
                    System.out.print(data[i] + " ");
            }
        }
    
    
    (2)、堆排序
    • 利用之前完成的LinkedMaxHeap实现排序功能。根据最大堆的性质依次返回值并打印出来,实现排序功能
    • 实验代码
    
     public void heapSort(Comparable[] data){
            LinkedMaxHeap linkedMaxHeap = new LinkedMaxHeap();
            for (int i = 0; i < data.length; i++)
                linkedMaxHeap.add(data[i]);
            for (int i = data.length-1; i>=0;i--)
                data[i]=linkedMaxHeap.removeMax();
        }
    
    
    
    (3)、桶排序
    • 桶排序的基本思想是将一个数据表分割成许多buckets,然后每个bucket各自排序,或用不同的排序算法,或者递归的使用bucket sort算法。基本流程是先建立一堆buckets,再遍历原始数组,并将数据放入到各自的buckets当中,对非空的buckets进行排序; 按照顺序遍历这些buckets并放回到原始数组中即可构成排序后的数组。

    • 实验代码

    
     public static void bucketSort(int[] arr){
    
            int max = Integer.MIN_VALUE;
            int min = Integer.MAX_VALUE;
            for(int i = 0; i < arr.length; i++){
                max = Math.max(max, arr[i]);
                min = Math.min(min, arr[i]);
            }
    
            //桶数
            int bucketNum = (max - min) / arr.length + 1;
            ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
            for(int i = 0; i < bucketNum; i++){
                bucketArr.add(new ArrayList<Integer>());
            }
    
            //将每个元素放入桶
            for(int i = 0; i < arr.length; i++){
                int num = (arr[i] - min) / (arr.length);
                bucketArr.get(num).add(arr[i]);
            }
    
            //对每个桶进行排序
            for(int i = 0; i < bucketArr.size(); i++){
                Collections.sort(bucketArr.get(i));
            }
    
    
        }
    
    
    
    (4)、二叉树排序
    • 利用二叉查找树的性质实现排序功能,利用类中findMin()方法将数组中的元素排序。
    • 实验代码
    
    public static void BinaryTreeSort(Comparable[] a){
            LinkedBinarySearchTree linkedBinaryTree = new LinkedBinarySearchTree();
            for (int i = 0; i < a.length; i++)
                linkedBinaryTree.add(a[i]);
            for (int i = 0; i < a.length; i++) {
                a[i] = linkedBinaryTree.findMin();
                linkedBinaryTree.remove(linkedBinaryTree.findMin());
            }
        }
    
    

    3、实验成果截图

  • 相关阅读:
    读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第三部分)
    Spring Boot进阶系列一
    职场进阶之七种武器
    大龄IT程序员的救赎之道
    Web Service
    生产者消费者问题
    SpringBoot集成Apache Shiro
    简单模拟医院叫号系统
    IT小团队管理者的突围之道
    内部推荐
  • 原文地址:https://www.cnblogs.com/lyxwatm/p/7822400.html
Copyright © 2011-2022 走看看