• 实验七


    学号 2019-2020-1823 《数据结构与面向对象程序设计》实验六报告

    班级: 1823

    姓名: 杨凯涵

    学号:20182321

    实验教师:王志强

    实验日期:2019年11月17日

    必修/选修: 必修

    1.实验内容

    实验一

    要求:定义一个Searching和Sorting类,并在类中实现linearSearch,SelectionSort方法,最后完成测试。
    要求不少于10个测试用例,提交测试用例设计情况(正常,异常,边界,正序,逆序),用例数据中要包含自己学号的后四位

    sorting类用的是选择排序,而searching类使用的是线性查找,这两个方法都是java算法里最最最最基本的算法了。代码如下

    选择排序算法
     public String selectionsort(String a)
        {
           String[] s = a.split("\s");
           int[] b = new int[s.length];
           for(int i=0;i<b.length;i++)
           {
               int num = Integer.parseInt(s[i]);
               b[i]=num;
           }
           for(int i=0;i<b.length-1;i++)
           {
               for(int j=i+1;j<b.length;j++)
               {
                   if(b[i]<b[j])
                   {
                       int t = b[i];
                       b[i]=b[j];
                       b[j]=t;
                   }
               }
           }
           String result="";
           for(int i=0;i<b.length;i++)
           {
               result+=" "+b[i];
           }
           return  result;
        }
    
    线性查找算法
     public  boolean linearSearch(String a, int target)
        {
            String[] s = a.split("\s");
            int data[]=new int[s.length];
            for(int i=0;i<s.length;i++)
            {
                int num = Integer.parseInt(s[i]);
                data[i] = num;
            }
            for(int i = 0;i<data.length;i++)
            {
                if(data[i]==target)
                    return true;
            }
            return false;
        }
    

    选择排序和线性查找算法的核心就是一股劲的往前冲,基本上没有什么很特殊、很难的地方。
    运行结果如下

    而异常情况运行结果为

    实验二

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

    首先在idea上运行,先把之前的两个类放入到题目要求的包中,然后再重新穿建立一个Test类,用来对其进行测试,测试代码如下

    测试查找
      public void testLinearSearch() {
            //正常
            assertEquals(new shiyan7.Searching().linearSearch("21 25 48 76 53 54 89 87 56 77 63 65 42 1 3 5 7 9 8 6 4 2 23 21",54),true);
            assertEquals(new shiyan7.Searching().linearSearch("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 23 21",5),true);
            //异常
            assertEquals(new shiyan7.Searching().linearSearch("12 3 5 48 7 98 78 62 6 45 87 6 3 548 6 98 63 45 78 6 23 21",28),false);
    
            assertEquals(new shiyan7.Searching().linearSearch("45 8 79 6 2 15 78 62 35 6 4 8 7 621 4 897 15 4564 23 21",34),false);
            //边界
            assertEquals(new shiyan7.Searching().linearSearch("21 25 48 76 53 54 89 87 56 77 63 65 42 1 3 5 7 9 8 6 4 2 23 21",2),true);
            assertEquals(new shiyan7.Searching().linearSearch("21 25 48 76 53 54 89 87 56 77 63 65 42 1 3 5 7 9 8 6 4 2 23 21",21),true);
            //正序
            assertEquals(new shiyan7.Searching().linearSearch("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2321",7),true);
            assertEquals(new shiyan7.Searching().linearSearch("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2321",19),true);
            //逆序
            assertEquals(new shiyan7.Searching().linearSearch("23 21 10 9 8 7 6 5 4 3 2 1",23),true);
            assertEquals(new Searching().linearSearch("23 21 10 9 8 7 6 5 4 3 2 1",21),true);
        }
    
      public void testSelectionsort() {
            //正常
            assertEquals(new shiyan7.sort().selectionsort("1 4 7 2 5 8 3 6 9 10")," 10 9 8 7 6 5 4 3 2 1");
            //逆序
            assertEquals(new shiyan7.sort().selectionsort("1 2 3 4 5 6 7 8 9 10")," 10 9 8 7 6 5 4 3 2 1");
            //正序
            assertEquals(new sort().selectionsort("10 9 8 7 6 5 4 3 2 1")," 10 9 8 7 6 5 4 3 2 1");
    
        }
    

    然后我们的运行结果如下所示

    在虚拟机中,我安装了junit

    但是发现这个东西属实难用,和idea里面的简直就是一个天一个地,所以经过考虑,我决定使用驱动程序在虚拟机里面进行测试

    实验三

    要求:参考http://www.cnblogs.com/maybe2030/p/4715035.html ,学习各种查找算法并在Searching中补充查找算法并测试

    我们按照里面的链接知道,编写相应的算法代码,并进行测试

    二分查找

      public  int BinarySearch2(int a[], int value, int low, int high)
        {
            int mid = low+(high-low)/2;
            if(a[mid]==value)
                return mid;
            if(a[mid]>value)
                return BinarySearch2(a, value, low, mid-1);
            if(a[mid]<value)
    
                return BinarySearch2(a, value, mid+1, high);
            return 0;
    
        }
    

    插入查找(其实和二分查找没什么区别)

     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);
            return 0;
    
        }
    

    斐波那契数列

     public static boolean FibonacciSearch(int[] table, int keyWord) {
            //确定需要的斐波那契数
            int i = 0;
            while (getFibonacci(i) - 1 == table.length) {
                i++;
            }
            //开始查找
            int low = 0;
            int height = table.length - 1;
            while (low <= height) {
                int mid = low + getFibonacci(i - 1);
                if (table[mid] == keyWord) {
                    return true;
                } else if (table[mid] > keyWord) {
                    height = mid - 1;
                    i--;
                } else if (table[mid] < keyWord) {
                    low = mid + 1;
                    i -= 2;
                }
            }
            return false;
        }
        //得到第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;
        }
    

    哈希线性查找(需要先提前构造哈希函数)

     public  static  boolean xianxing(Comparebale[] data , Comparebale target)
        {
            int num = target.geti()%9;
            boolean i ;
            while (data[num]!=null) {
    
    
                if(data[num].geti()==target.geti())
                    return true;
                else
                    num++;
    
            }
            return  false;
        }
    

    这里我的哈希函数设置为h%9,大家可以自行设定

    二叉树查找

      public static  boolean erchashu(Comparebale tree, Comparebale target)
        {
            while (tree!=null)
            {
                if(tree.geti()<target.geti())
                {
                    tree=tree.next;
                }
                else if (tree.geti()>target.geti())
                {
                    tree = tree.secondnext;
                }
                else if(tree.geti()==target.geti())
                    return true;
            }
            return false;
        }
    

    二叉树之前也是要先构建

    public class erchashu {
        Comparebale tree = new Comparebale(-1);
        Comparebale head = new Comparebale(-1);
        int[] a = new int[12];
        public erchashu()
        {
            head.setNext(tree);
        }
        public void s(int[] b)
        {
            tree.setI(b[0]);
            for(int i=1;i<b.length;i++)
            {
                Comparebale c = new Comparebale(b[i]);
                tree = head.getNext();
             while (tree.geti()!=b[i])
             {
                 if(tree.geti()<b[i]&&(tree.getNext()!=null))
                 {
                     tree = tree.getNext();
                 }
                 else if(tree.geti()<b[i]&&tree.getNext()==null)
                 {
                     tree.setNext(c);
                     tree=c;
                 }
                 else  if(tree.geti()>b[i]&&tree.getSecondnext()!=null)
                     tree = tree.getSecondnext();
                 else if(tree.geti()>b[i]&&tree.getSecondnext()==null)
                 {
                     tree.setSecondnext(c);
                     tree = c;
                 }
             }
    
    
            }
    
        }
        public String toString( int[] a)
        {
            s(a);
            String result = "";
            
            for(int i=0;i<a.length;i++)
            {
                result =result;
            }
            return  result;
        }
        public Comparebale get()
        {
            return head.getNext();
        }
    
    }
    
    

    接着是分块查找

     public static boolean blooksearch(int[] a ,int key)
        {
            int[] b = new int[3];
            int n = a.length/3;
            int max = a[0];
            int j=0;
            while (n<=9)
            {
                for(int i=n-3;i<n;i++)
                {
                    if(max<a[i])
                        max = a[i];
                }
                b[j]=max;
                j++;
                n=n+3;
            }
            for(int i=0;i<b.length;i++)
            {
                if(b[i]>=key)
                {
                   for(int l = (i+1)*3-1;l>=(i+1)*3-3;l--)
                   {
                       if(a[l]==key)
                           return true;
                   }
                   return  false;
                }
    
            }
            return false;
        }
    

    最后测试的运行截图为

    实验四

    要求:补充实现课上讲过的排序方法:希尔排序,堆排序,二叉树排序等(至少3个)
    测试实现的算法(正常,异常,边界)
    提交运行结果截图

    希尔排序

     public String   sort (int[] arr)
        {
            for(int gap = arr.length/2;gap>0;gap/=2)
            {
                for(int i=gap;i<arr.length;i++)
                {
                    int j =i;
                    while (j-gap>=0&&arr[j]<arr[j-gap])
                    {
                        int t = arr[j];
                        arr[j]=arr[j-gap];
                        arr[j-gap]=t;
                        j-=gap;
                    }
                }
            }
            String result = "";
            for(int i=0;i<arr.length;i++)
            {
                result += " "+arr[i];
            }
            return result;
        }
    

    堆排序

        public static void heapify(int[] arrays, int currentRootNode, int size) {
    
            if (currentRootNode < size) {
                //左子树和右字数的位置
                int left = 2 * currentRootNode + 1;
                int right = 2 * currentRootNode + 2;
    
                //把当前父节点位置看成是最大的
                int max = currentRootNode;
    
                if (left < size) {
                    //如果比当前根元素要大,记录它的位置
                    if (arrays[max] < arrays[left]) {
                        max = left;
                    }
                }
                if (right < size) {
                    //如果比当前根元素要大,记录它的位置
                    if (arrays[max] < arrays[right]) {
                        max = right;
                    }
                }
                //如果最大的不是根元素位置,那么就交换
                if (max != currentRootNode) {
                    int temp = arrays[max];
                    arrays[max] = arrays[currentRootNode];
                    arrays[currentRootNode] = temp;
    
                    //继续比较,直到完成一次建堆
                    heapify(arrays, max, size);
                }
            }
        }
        public static void maxHeapify(int[] arrays, int size) {
    
            // 从数组的尾部开始,直到第一个元素(角标为0)
            for (int i = size - 1; i >= 0; i--) {
                heapify(arrays, i, size);
            }
    
        }
        public static String dui(int[] arrays)
        {
            for (int i = 0; i < arrays.length; i++) {
    
                //每次建堆就可以排除一个元素了
                maxHeapify(arrays, arrays.length - i);
    
                //交换
                int temp = arrays[0];
                arrays[0] = arrays[(arrays.length - 1) - i];
                arrays[(arrays.length - 1) - i] = temp;
    
            }
            String result="";
            for(int i=0;i<arrays.length;i++)
            {
                result =result+ "  "+arrays[i];
            }
            return  result;
        }
    

    二叉树排序

     public void s(int[] b)
        {
            tree.setI(b[0]);
            for(int i=1;i<b.length;i++)
            {
                Comparebale c = new Comparebale(b[i]);
                tree = head.getNext();
             while (tree.geti()!=b[i])
             {
                 if(tree.geti()<b[i]&&(tree.getNext()!=null))
                 {
                     tree = tree.getNext();
                 }
                 else if(tree.geti()<b[i]&&tree.getNext()==null)
                 {
                     tree.setNext(c);
                     tree=c;
                 }
                 else  if(tree.geti()>b[i]&&tree.getSecondnext()!=null)
                     tree = tree.getSecondnext();
                 else if(tree.geti()>b[i]&&tree.getSecondnext()==null)
                 {
                     tree.setSecondnext(c);
                     tree = c;
                 }
             }
    
    
            }
    
        }
    

    代码测试运行截图为

    异常截图

    实验五

    要求:编写Android程序对实现各种查找与排序算法进行测试
    提交运行结果截图
    推送代码到码云

    进行布局并放入代码进去之后,结果如图

    3. 实验过程中遇到的问题和解决过程

    问题一:如何进行堆排序算法?
    问题一解决方法:了解堆排序之前就必须要知道一个完全二叉树的概念,何为完全二叉树,如下图

    即除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐。它和满二叉树这个概念是一定要区分开的。从总体来讲,堆排序就是讲数据看成是完全二叉树类型,然后用二叉树的特性来进行排序的一种算法。

    如下图

    这是一个完全二叉树,而二叉树的数据其实都存储进了数组里面,左子树的序数其实是其父亲的2i+1,右子数的序数是其父亲的2i+2,可以按照这个特性将二叉树的值都依次附进数组里,接着我们发现左右子树都符合最大堆,但是父类子树不符合,则我们需要先对其父亲子树进行操作,让7在根节点上。

    那这样右子数又不符合了,那我们又要对右子数进行调换,则

    右子数变成了这样

    这属于建堆成功,最后我们还需要进行调换,将最开头的元素与最末尾的元素进行调换,如下图

    堆排序是通过不断的这样建堆的过程完成其排序的,详细我自己手写的下图

    则这样我们就实现了堆排序,具体代码在我的实验过程里有了。

    • 问题2:分块查找的算法是如何设计的?
    • 问题2解决方法:分块查找其实是线性查找的改良版,它把一个线性集合的数组分成数个模块,每个模块有着的一个最大关键字作为索引

    将所有的最大索引变成一个索引表,查找分为两部分,先对索引表进行二分查找或是顺序查找,以确定待查记录在哪一块中,然后,在已经确定的块中用顺序法进行查找。具体代码可看我的实验过程。

    其他(感悟、思考等)

    • 算法的排序查找是一个及其复杂的东西,让人掉发,关键在于设计算法出来后如何实现非常的困难,本人也只能上网去查阅他人资料学习。
    • 只有在打下坚实的基础下,才能把这些排序算法打出来,否则会极易出现错误。

    参考资料

    《Java程序设计与数据结构教程(第二版)》

    《Java程序设计与数据结构教程(第二版)》学习指导

  • 相关阅读:
    在GridView1的RowEditing获取GridView1里面绑定的某一字段
    仿淘宝网站的导航标签效果!
    ASP.NET Cookies简单应用 [ASP.NET | Cookies]
    UpdatePanel使用时注意说明
    Asp.net(C#)显示所有缓存 清除所有缓存
    计算字符在字符串是出现的次数
    新接触了ActionScript3.0 拿出来晒晒~
    转载Windows XP_32bit、Windows 7_32bit、Windows 7_64bit乱序任意安装方法
    新博客庆祝
    Android 电视关闭的动画效果
  • 原文地址:https://www.cnblogs.com/yangkaihan/p/11876757.html
Copyright © 2020-2023  润新知