数据结构 -- 单链表

 一.链表的概念

定义:链表是一种物理存储上非连续,数据元素的逻辑顺序通过链表中的指针链接次序,实现的一种线性存储结构。

特点:链表由一系列节点(链表中每一个元素称为节点)组成,节点在运行时动态生成 (malloc),每个节点包括两个部分:①  一个是存储数据元素的数据域 ② 另一个是存储下一个节点地址的指针域。简单的说 链表一部分是数存储数据的  一部分是存储下一个节点的地址的

链表的构成(初始化)

public class Node<E>{

//该节点的数据
    E val;
//下一个节点
    Node<E> next;

//构造器
    Node<E>(E x){
    val = x;
    next = null;
  }
   
}

      链表节点分为两个域

      数据域:存放各种实际的数据,如:num、score等

      指针域:存放下一节点的首地址,如:next等.

链表的操作(增删改查)

①链表的遍历:

/*
*实现思路:由于链表其实就是把他看做 一圈小朋友进行手拉手进行游戏
*我们只需要判断他的下一个是否有签这下一个小朋友的手 就可以进对链表进行遍历操作
*/


public static int getListNode(Node node){
    int length = 0;
    while(node!= null){
      node = node.next;
//TODO:可以在这边把链表的每个节点打印出来
      length++;
  }
   return length;
}

②链表的插入:

示意图:

/*
*链表的插入 ①头部插入:我们只要链表的投节点是不存在节点的 因此我们把需要插入的节点
*的指针域指向投节点的地址即可

public class myLinkedList<E>{

    private final Node<E> head, tail;
    private int size;

    // 单链表链表节点
    private static class Node<E> {
        E val;
        Node<E> next;

        Node(E val) {
            this.val = val;
        }
    }

    // 构造函数初始化头尾节点
    public MyLinkedList2() {
//其实这两个节点可以看成两个 哨兵节点(虚拟的节点)
        this.head = new Node<>(null);
        this.tail = new Node<>(null);
        head.next = tail;

        this.size = 0;
    }


public void addFirst(E e){
    Node<E> newNode = new Node(e);
    Node<E> temp = new Node();

    newNode.next = temp;
    head.next = newNode;
    
    size++;
 }
}

可以看出上面的代码 进行初始化了    private final Node<E> head, tail;   private int size;

对于节点head 和 tail 为了我们对边界的控制 我们所设立的哨兵节点 他是 head永远是头节点,tail永远是最末尾的节点。

③链表的删除:

(1)删除头节点

(2)删除尾节点

(3)删除指定位置节点

    /**
     * 删除头节点  就是把该节点置为null
     * @return 节点数据
     */
    public E removeFirst() {
        //先原本的头节点找出
        Node<E> x = head.next;
        //只需要将我们的哨兵节点指向 下下一个节点即可
        head.next = head.next.next;
        x = null;
        size--;

        return x.val;
    }

    /**
     * 删除尾节点
     * @return 节点信息
     */
    public E removeLast() {
        //原本的尾节点
        Node<E> x = getNode(size-1);
        Node<E> temp ;
        if(size-2>0){
            //最后一个节点的上一个节点
            temp = getNode(size-2);
        }else {
            temp = head;
        }

        temp.next = tail;
        //将原本的node 的指针域变为null
        x.next = null;

        return x.val;
    }

    /**
     * 删除对应index 的节点
     * @param index 索引
     * @return 节点信息
     */
    public E remove(int index) {
        Node<E> node = getNode(index);
        Node<E> perv;

        if(size-1>0){
            perv = getNode(index-1);
        }else {
            perv = head;
        }
        perv.next = node.next;
        node.next = null;

        return perv.val;
    }

④获取链表信息:

    /**
     * 获取头节点
     * @return 信息
     */
    public E getFirst() {
        return head.next.val;
    }

    public E getLast() {
        //获取到尾节点
        return getNode(size - 1).val;
    }

    /**
     * 获取指定节点
     * @param index 索引
     * @return 信息
     */
    public E get(int index) {
        return getNode(index).val;
    }

⑤修改链表信息:

   /***** 改 *****/

    public E set(int index, E element) {
        checkElementIndex(index);
        Node<E> p = getNode(index);

        E oldVal = p.val;
        p.val = element;

        return oldVal;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值