20162302 实验一《线性结构》实验报告

实 验 报 告

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

姓名:杨京典

班级:1623

学号:20162302

实验名称:线性结构

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


实验目的与要求:

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

实验内容、步骤与体会:

实验内容:


测试ArrayList和LinkedList

首先要在帮助文档里面找到这两个类的用法
ArrayList:
1062717-20171001224909419-76233701.png
LinkedList:
1062717-20171001225104669-194284551.png

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

分别是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;
        }
    }

转载于:https://www.cnblogs.com/yangjingdian/p/7617559.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简要的 C 语言栈实验报告: 1. 实验目的 本实验主要目的是通过实现一个栈的数据结构,来加深对于栈以及数据结构的理解,并且通过实践掌握 C 语言基本操作。 2. 实验原理 栈是一种线性数据结构,它可以通过先进后出(LIFO)的方式来进行数据存取。在栈中,数据的插入和删除操作只能在栈顶进行,因此它是一种操作受限的数据结构。 本次实验中,我们将使用 C 语言来实现一个基本的栈数据结构,包括栈的创建、入栈、出栈、判断栈是否为空等基本操作。通过这些操作,我们可以更好地理解栈的操作流程以及相应的算法。 3. 实验过程 首先,我们需要定义一个结构体来表示栈的数据结构: ``` #define MAX_SIZE 100 typedef struct stack { int top; int data[MAX_SIZE]; } Stack; ``` 其中,MAX_SIZE 定义了栈的最大容量,top 表示当前栈顶的位置,data 数组用于存储栈中的数据。 接下来,我们需要实现栈的基本操作。这些操作包括:栈的创建、入栈、出栈、判断栈是否为空等。 ``` void init(Stack *s) { s->top = -1; } int is_empty(Stack *s) { return s->top == -1; } int is_full(Stack *s) { return s->top == MAX_SIZE - 1; } int push(Stack *s, int value) { if (is_full(s)) { return 0; } s->top++; s->data[s->top] = value; return 1; } int pop(Stack *s) { if (is_empty(s)) { return -1; } int value = s->data[s->top]; s->top--; return value; } ``` 其中,init 函数用于初始化栈,is_empty 和 is_full 函数分别用于判断栈是否为空和是否已经满了。push 函数用于将数据入栈,pop 函数用于将数据出栈。 最后,我们可以编写一个简单的测试程序来测试我们实现的栈数据结构: ``` int main() { Stack s; init(&s); push(&s, 1); push(&s, 2); push(&s, 3); while (!is_empty(&s)) { printf("%d\n", pop(&s)); } return 0; } ``` 该程序将会创建一个栈,将 1、2、3 入栈,并且依次将它们出栈并打印输出。 4. 实验结果 通过编写测试程序,我们可以看到输出结果: ``` 3 2 1 ``` 这表明我们实现的栈数据结构可以正常工作,能够实现基本的入栈、出栈等操作。 5. 实验总结 通过本次实验,我们更加深入地理解了栈这种数据结构,同时也掌握了 C 语言实现栈的基本方法。在实现过程中,我们还学习了一些基本的算法思想,例如 LIFO 等。这些知识对于我们进一步学习和掌握其他数据结构以及算法都非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值