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;
            }
        }
    
  • 相关阅读:
    Java实现 洛谷 P1049 装箱问题
    (Java实现) 洛谷 P1781 宇宙总统
    (Java实现) 洛谷 P1319 压缩技术
    (Java实现) 蓝桥杯 国赛 重复模式
    qt编写一个只能运行单个实例的程序,不用Windows API
    Chaos Software Google Sync v10.1.1.0 和Syncovery Pro
    C++中new和delete的背后( call edx 调用虚表内的第二个函数(析构函数))
    C++中实现回调机制的几种方式(一共三种方法,另加三种)
    如何将Icon转成Bitmap(对ICON的内部格式讲的比较清楚)
    深入解析控制器运行原理
  • 原文地址:https://www.cnblogs.com/yangjingdian/p/7617559.html
Copyright © 2011-2022 走看看