实验二 线性表综合实验(3)

来源:互联网 发布:ruby和python哪个强大 编辑:程序博客网 时间:2024/06/17 12:44

实验二之双链表

实验内容:

用双链表实现学生成绩管理

实验步骤:

1.沿用上一次实验使用的javabean类即学生类来保存学生成绩:

2.编写内部类:

    private static class Node<E> {        E element;//存储数据        Node<E> next = this.next;// 下结点        Node<E> previous = this.previous;// 上节点        Node (){        }   //编写一个无参构造,维持稳定性        Node(E element) {//单参构造方法            this.element = element;            this.next = next;            this.previous = previous;        }    //打印方法        public String toString() {            return this.element.toString();        }    }

3.编写双链表相关的方法和属性:

    public boolean addFirst(Object o) {        addAfter(new Node(o), header);        return true;    }    public boolean addLast(Object o) {        addBefore(new Node(o), header);        return true;    }    public boolean add(Object o) {        return addLast(o);    }    public boolean add(int index, Object o) {        addBefore(new Node(o), getNode(index));        return true;    }    public E remove(int index) {        Node e = entry(index);        remove(e);        return (E) e.element;    }    public String toString() {        StringBuffer s = new StringBuffer("[");        Node node = header;        for (int i = 0; i < size; i++) {            node = node.next;            if (i > 0)                s.append("|");            s.append(node.toString());        }        s.append("]");        return s.toString();    }    private void addBefore(Node newNode, Node node) {        newNode.next = node;        newNode.previous = node.previous;        newNode.next.previous = newNode;        newNode.previous.next = newNode;        size++;    }    private void addAfter(Node newNode, Node node) {        newNode.previous = node;        newNode.next = node.next;        newNode.next.previous = newNode;        newNode.previous.next = newNode;        size++;    }    private void remove(Node e) {        if (e == header)            throw new NoSuchElementException();        // 将前一节点的next引用赋值为e的下一节点        e.previous.next = e.next;        // 将e的下一节点的previous赋值为e的上一节点        e.next.previous = e.previous;        // 上面两条语句的执行已经导致了无法在链表中访问到e节点,而下面解除了e节点对前后节点的引用        e.next = e.previous = null;        // 将被移除的节点的内容设为null        e.element = null;        // 修改size大小        size--;    }    private Node getNode(int index) {        if (index < 0 || index >= size)            throw new IndexOutOfBoundsException();        Node node = header.next;        for (int i = 0; i < index; i++)            node = node.next;        return node;    }    // 获取双向链表中指定位置的节点    private Node<E> entry(int index) {        if (index < 0 || index >= size)            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);        Node<E> e = header;        // 获取index处的节点。        // 若index < 双向链表长度的1/2,则从前先后查找;        // 否则,从后向前查找。        if (index < (size >> 1)) {            for (int i = 0; i <= index; i++)                e = e.next;        } else {            for (int i = size; i > index; i--)                e = e.previous;        }        return e;    }}

3.编写测试类并运行:

public class TestDemo_2 {    public static void main(String[] args) {        LinkedList<Student> all = new LinkedList<Student>();        all.add(new Student("A", "201611671301", 80.0));        all.add(new Student("B", "201611671303", 50.0));        all.add(new Student("C", "201611671302", 60.0));        all.add(new Student("D", "201611671309", 90.0));        System.out.println(all.toString());        all.remove(0);        System.out.println("+++++++++++++++++");        System.out.println(all.toString());    }}

4.运行结果:

这里写图片描述

实验相关说明:

  • 本次实验并没有采用对单链表使用的内部类和递归调用的设计模式,原因是本人能力尚浅,还是理不清思路,待以后有时间再对代码进行结构的优化
  • 本次实验相比上次的实验采用了泛型,编写了一系列的private方法来提高代码的利用率和可读性。
  • 本次实验的难点主要在于节点数据的添加,删除操作,因为一个node关联到前后俩个节点,所以在进行重连接时要注意顺序。