zoukankan      html  css  js  c++  java
  • 20162302 实验一《线性结构》实验报告

    实 验 报 告

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

    姓名:杨京典

    班级:1623

    学号:20162302

    实验名称:线性结构

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


    实验目的与要求:

    1.测试ArrayList和LinkedList
    2.实现有序线性表的合并
    3.用数组实现线性表List
    4.用链表实现线性表List
    5.源码分析

    实验内容、步骤与体会:

    实验内容:


    测试ArrayList和LinkedList

    首先要在帮助文档里面找到这两个类的用法
    ArrayList:

    LinkedList:

    • 由于时间有限,本次试验就只对两个类的三个方法进行测试

    分别是ArrayList类的add()remove()isEmpty();以及LinkedList类的add()remove()contains()

    关于测试,一共有两种方法,第一种是直接调用这个类,观察运行结果

    public class Lin_1_arr {
        public static void main(String[] args) {
            String zhanghaolin = "zhl";
            String liuyuxing = "lyx";
            String mapingchuan = "mpc";
            ArrayList arrayList = new ArrayList();
            arrayList.add(zhanghaolin);
            arrayList.add(0, liuyuxing);
            arrayList.add(mapingchuan);
            System.out.println(arrayList);
            System.out.println(arrayList.get(1));
            arrayList.clear();
            System.out.println(arrayList);
        }
    }
    

    这样的方法对于自己不熟悉的类使用要方便的多,相对直观,可以直接看到运行结果。
    但是这样又看不出来运行结果产生的数据的类型。第二种方法就可以避免这一问题,使用JUnit测试运行结果

    public class Lin_1_arr {
        public void testNormal() {
            String zhanghaolin = "zhl";
            String liuyuxing = "lyx";
            String mapingchuan = "mpc";
            ArrayList arrayList = new ArrayList();
            arrayList.add(zhanghaolin);
            arrayList.add(liuyuxing);
            arrayList.add(mapingchuan);
            assertEquals("[zhl, lyx, mpc]",arrayList.toString());
            arrayList.remove(1);
            assertEquals("[zhl, mpc]",arrayList.toString());
            assertEquals(false ,arrayList.isEmpty());
            arrayList.clear();
            assertEquals(true ,arrayList.isEmpty());
        }
    }
    

    用于举例子的代码是测试ArrayList的代码,LinkedList的测试代码可以通过链接在码云上找到。

    实现有序线性表的合并

    • 要求是写一个mergeSortedList方法,使其可以将输入的两个有序的数组排序并输出
    • 首先要注意到,数组是有序的,所以为排序省去了时间,只需要将两个数组最前面的数据比较就可以了
    • 其次要规划好方法在运行的时候的流程,我的流程是设定两个指针,在设置一个盛放数据的数组
    ArrayList cList = new ArrayList();
    int i = 0;
    int j = 0;
    
    • 然后要做的就是根据指针提取数组中的元素并进行比较,并根据比较的情况放入新的数组以及移动指针
    if (aList.get(i).compareTo(bList.get(j)) < 0) {
                    cList.add(aList.get(i));
                    i++;
                } else {
                    cList.add(bList.get(j));
                    j++;
                }
    
    • 接下来设置限制条件,从而避免指针移动到没有元素的地方
    while (i<aList.size() && j <bList.size()) {
                if (aList.get(i).compareTo(bList.get(j)) < 0) {
                    cList.add(aList.get(i));
                    i++;
                } else {
                    cList.add(bList.get(j));
                    j++;
                }
            }
    
    • 限制条件是有了,但是限制的有点过分了,造成有些元素还没有参与比较就被扔掉了
    if (i<aList.size())
                for (int a = i; a<aList.size()-1; a++)
                    cList.add(aList.get(a));
            if (j<aList.size())
                for (int a = j; a<aList.size()-1; a++)
                    cList.add(bList.get(a));
    

    这样就可以达到将两个数组重新排序并输出的过程了,完整代码

    用数组实现线性表List

    • 首先要规定数组的大小,但是也要做到让数组的容量可以扩大,所以就要写一个方法,当数组被元素放满的时候要调用这个方法以扩充这个数组的容量
    public void expandCapacity() {
                T[] larger = (T[]) (new Object[data.length * 2]);
                for (int index = 0; index < count; index++)
                    larger[index] = data[(front + index) % data.length];
                front = 0;
                n = count;
                data = larger;
            }
    
    • add()方法是最基础的方法,就是讲输入的元素放到数组里面,然后移动指针,判断指针的位置和数组的容量,在需要的时候调用expandCapacity()方法
    public void add(T element) {
                if (count == data.length)
                    expandCapacity();
                data[n] = element;
                n = (n + 1) % data.length;
                count++;
            }
    
    • 接下来就是关于remove()方法的使用,为了增强兼容性,我创建了两个remove()一个需要输入参数,可以删除指定位置的数据;另一个不需要,默认删除最后一个数据
            public void remove(){
                if (count!=0) {
                    data[count-1] = null;
                    count--;
                }
            }
            public void remove(int a){
                if(a<data.length)
                    for(int i = a; i<count-1;i++) {
                        data[a] = data[a + 1];
                        data[count-1]=null;
                        count--;
                    }
            }
    
    • 有了指针isEmpty方法就非常好实现了,只需判断指针是否指向零就可以了
    public boolean isEmpty(){
                return count==0;
            }
    
    • toString()方法虽然存在感很差,但也是必不可少的一个方法,在调试的时候它的意义就体现出来了
    public String toString(){
                String a="";
                for (int i = 0; i<data.length;i++)
                    a+=" "+data[i];
                return a;
            }
    

    这样就可以简单的通过数组实现出List了,完整代码测试代码

    用链表实现线性表List

    • 链表由一个个小数据元组成,由盛放的数据和下一位指向两个关键部分组成。
    private data(T dataPortion) {
                data = dataPortion;
                next = null;
            }
    
    • 然后就要声明出首项和指针
    private data first;
    private int length = 0;
    
    • 和线性结构不同,不能依靠指针直接确定位置,所以在添加的时候就要判断数组是否为空,如果是空的就放在建立好的first,如果不是的话就可以建立一个新的数据元并让前一位指向它
    public boolean add(T object) {
            data newNode = new data(object);
            if (isEmpty()) {
                first = newNode;
            } else {
                data lastNode = get(length);
                lastNode.next = newNode;
            }
            length++;
            return true;
        }
    
    • 在上面的方法中需要用到一个获取数据的get()方法以获取相应位置的数据,可以通过一个for循环来实现。要注意判断输入的值是否可用,可以用assert来筛选,也可以用if语句来判断。
    private data get(int givenPosition) {
            assert (!isEmpty()) && (1 <= givenPosition) && (givenPosition <= length);
            data currentNode = first;
            for (int i = 1; i < givenPosition; i++) {
    
                currentNode = currentNode.next;
            }
            assert currentNode != null;
            return currentNode;
        }
    
    • 有了get方法在接下来的创建中就会产生很多优势,比如更便捷的写出add()允许用户在指定位置插入元素的add()方法
    public boolean add(int n, T object) {
            if ((n >= 1) && (n <= length + 1)) {
                data newData = new data(object);
                if (isEmpty() || n == 1) {
                    newData.next = first;
                    first = newData;
                } else {
                    data dataBefore = get(n - 1);
                    data dataAfter = dataBefore.next;
                    newData.next = dataAfter;
                    dataBefore.next = newData;
                }
                length++;
                return true;
    
            } else return false;
        }
    
    • 链表的remove()方法比线性表的要好写的多,不用在删除元素的时候将后面的元素全部移位,只需要重新连接删除元素前后就可以
    public Object remove(int n) {
            Object result = null;
            if (n < 1 || n > length || isEmpty()) {
                System.out.println("Error");
                return result;
            } else if (n != 1) {
                data deleteData = get(n);
                data dataBefore = get(n - 1);
                dataBefore.next = deleteData.next;
                length--;
                return deleteData;
            } else {
                result = first.data;
                first = first.next;
                length--;
                return result;
            }
        }
    
  • 相关阅读:
    【乱侃】How do they look them ?
    【softeware】Messy code,some bug of Youdao notebook in EN win7
    【随谈】designing the login page of our project
    【web】Ad in security code, making good use of resource
    SQL数据库内存设置篇
    关系数据库的查询优化策略
    利用SQL未公开的存储过程实现分页
    sql语句总结
    sql中使用cmd命令注销登录用户
    SQLServer 分页存储过程
  • 原文地址:https://www.cnblogs.com/yangjingdian/p/7617559.html
Copyright © 2011-2022 走看看