链表(单向链表,双向链表)

1.链表的基本介绍

   首先链表是以节点的方式存储数据的,每个节点包含数据域(data),节点域(next),链表的每个节点在计算机中存储的位置是不连续的和随机的,优点就是数据的插入和删除比较好,而查找数据效率不是太好(因为链表无法像静态数据一样随机读取数据,必须按照顺序找到对应的数据为止)。

 

 2.单向链表

  2.1.什么是单向链表

   单向链表就像是火车,所有的节点串联成一列,而且指针所指的方向一样,也就是链表中每个节点除了存储原本的数据,还有存储下一个节点的存储地址。如下图所示:

 

 节点类的代码实现

class SingleNode {
    public Object object; //节点数据
    public SingleNode next; //指向下一个节点

    public SingleNode() {

    }

    public SingleNode(Object object, SingleNode next) {
        this.object = object;
        this.next = next;

    }
}

  

 2.2.单向链表实现(增加,删除,修改,查看)数据

  

/**
 * 单链表的实现
 */
public class SingleLinkList {
    private SingleNode first; //定义头结点
    private SingleNode last;  //定义尾节点
    private int size;   //定义链表的节点数

    /**
     * 判断链表是否为空
     * @return
     */
    public boolean isEmpty() {
        return first == null;
    }

    /**
     * 在链表的头部和尾部添加元素
* 思路分析:当链表为空时,就相当于在链表的头部添加数据,所以把新添加的节点赋值给头结点(尾节点),
* 当链表不为空时,就相当于于在链表的尾部添加数据,这时候我们就是把尾部的指针指向新添加的节点(即last.next=node),然后把新添加的节点赋值到
* 最后节点 (即last=node) */ public void add(Object object) { SingleNode node = new SingleNode(object, null); if (isEmpty()) { first = node; } else { last.next = node; } last = node; size++; } /** * 在指定的节点增加元素 * 思路分析:首先我们需要判断添加的位置是否满足条件(index>0 && index<size),然后我们需要找到指定索引位置的元素和它的上一个位置的元素,所以用到
* 两个指针来记录索引位置的元素和它上一个位置的元素,最后把 (before.next=node,node.next=temp),这就相当于把before指向node,node指向当前节点(temp)即可。 * @param index * @param object */ public void addElement(int index, Object object) { SingleNode node = new SingleNode(object, null); if (index > 0 && index < size) { SingleNode temp = first; SingleNode before = null; for (int i = 0; i < index; i++) { before = temp; temp = temp.next; } before.next = node; node.next = temp; size++; } } /** * 展示链表中的节点元素 */ public void show() { if (!isEmpty()) { SingleNode current = first; while (current != null) { System.out.println(current.object); current = current.next; } } } /** * 获得指定节点的元素 * 思路分析:定义一个指针,循环到指定位置,把元素取出即可 * @param index * @return */ public Object get(int index) { if (index > 0 && index < size) { if (!isEmpty()) { SingleNode temp = first; for (int i = 0; i < index; i++) { temp = temp.next; } return temp.object; } } return null; } /** * 删除指定节点的元素 * 思路分析:需要定义两个指针来记录要删除的节点和要删除节点的上一个节点,然后 把before.next=temp.next即可。 * @param index */ public void remove(int index) { if (index > 0 && index < size) { if (!isEmpty()) { SingleNode temp = first; SingleNode beforeTemp = null; for (int i = 0; i < index; i++) { beforeTemp = temp; temp = temp.next; } beforeTemp.next = temp.next; } } } /** * 修改指定节点的指定元素 * * @param index * @param object */ public void update(int index, Object object) { if (index > 0 && index < size) { if (!isEmpty()) { SingleNode temp = first; for (int i = 0; i < index; i++) { temp = temp.next; } temp.object = object; } } } /** * 实现链表的反向打印
* 思路分析:利用栈先进后出的特点,首先把元素放到栈中,然后再取出,即可。 */ public void rePrint() { Stack<SingleNode> stack = new Stack<SingleNode>(); if (!isEmpty()) { SingleNode current = first; while (current != null) { stack.push(current); current = current.next; } while (stack.size() > 0) { System.out.println(stack.pop().object); } } } /** * 将单链表反转 */ public void reversetList() { SingleNode current = first; SingleNode before = null; while (current != null) { last = before; before = current; current = current.next; before.next = last; } current = before; while (current != null) { System.out.println(current.object); current = current.next; } }

  

 

  

  

   

猜你喜欢

转载自www.cnblogs.com/xiaofuzi123456/p/12676819.html