数据结构与算法03-链表

链表(linked_list)

链表内还有一种特殊的节点称为哨兵 (Sentinel) 节点,也叫做哑元 ( Dummy) 节点,

它不存储数据,通常用作头尾,用来简化边界判断

哨兵其实就是初始化的一个节点,保证链表中永远都不为空,哨兵不参与增删改查,
 

  1. 单向链表

/**
 * 单向链表
 */
public class SinglyLinkedList implements Iterable<Integer> {

    private Node head = null; //头部
    //哨兵--头部节点
    //不参与遍历增删改等
    private Node head1 = new Node(1,null);


    /**
     * 节点类
     */
    private static class Node {
        int value;//值
        Node next;//下一个节点的指针

        public Node(int value, Node next) {
            this.value = value;
            this.next = next;
        }
    }

    /**
     * 增加至头部
     *
     * @param value
     */
    public void addFirst(int value) {
        head = new Node(value, head);
    }

    /**
     * 增加至尾部
     * 需要循环遍历才能找到尾部
     */
    public void addLast(int value) {
        Node p = head;
        while (p != null && p.next != null) {
            p = p.next;
        }
        //如果链表中没有数据,调用增加至头部的方法
        if (p == null) {
            addFirst(value);
        } else {
            p.next = new Node(value, null);
        }
    }

    /**
     * 根据下标寻找节点值
     */
    public int getByIndex(int index) {
        Node p = head;
        int i = 0;
        while (p != null) {
            if (i == index) {
                return p.value;
            }
            i++;
            p = p.next;
        }
        if (p == null) {
            throw new ArrayIndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));
        }
        return 0;
    }

    /**
     * 插入指定索引位置
     */
    public void insertIndex(int index,int value){
        if(index == 0){
            addFirst(value);
            return;
        }
        //寻找插入节点之前的那个节点
        Node p = head;
        int i = 0;
        while (p != null){
            if(i == (index-1)){
                p.next = new Node(value,p.next);
                return;
            }
            i++;
            p = p.next;
        }
        if (p == null) {
            throw new ArrayIndexOutOfBoundsException(String.format("index [%d] 不合法%n", index));
        }
    }

    /**
     * 删除第一个节点
     */
    public void removeFirst(){
        if(head == null){
            return;
        }
        head = head.next;
    }

    /**
     * 删除指定位置节点
     */
    public void remove(int index){
        if(index == 0){
            removeFirst();
        }else{
            Node p = head;
            int i = 0;
            while (p != null){
                if(i == (index-1)){
                    System.out.println(i);
                    if(p.next == null){
                        return;
                    }
                    p.next = p.next.next;
                    return;
                }
                i++;
                p = p.next;
            }
        }
    }

    /**
     * 遍历1
     * while循环
     */

    public void loop1(Consumer<Integer> consumer) {
        Node p = head;
        while (p != null) {
            consumer.accept(p.value);
            p = p.next;
        }
    }

    /**
     * 遍历2
     * for循环
     */

    public void loop2(Consumer<Integer> consumer) {
        for (Node p = head; p != null; p = p.next) {
            consumer.accept(p.value);
        }
    }

    /**
     * 遍历3
     * 迭代器循环
     */
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node p = head;

            @Override
            public boolean hasNext() {
                return p != null;
            }

            @Override
            public Integer next() {
                int v = p.value;
                p = p.next;
                return v;
            }
        };
    }

    /**
     * 遍历4
     * 递归算法遍历
     */
    public void loop3(Node curr) {
        System.out.println(curr.value);
        if(curr == null){
            return;
        }
        loop3(curr.next);
    }
}
  1. 双向链表
private static class Node{
        Node prev;//头节点
        int value;
        Node next;//尾节点
        public Node(Node prev,int value,Node next){
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

        head = new Node(null,1,null);
        tail = new Node(null,2,null);
        head.next = tail;
        tail.prev = head;
  1. 循环链表

哨兵链表的头尾都指向自己,将来有元素的时候,尾部元素的尾指向哨兵

private static class NodeRound{
        NodeRound prev;//头节点
        int value;
        NodeRound next;//尾节点
        public NodeRound(NodeRound prev,int value,NodeRound next){
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    NodeRound nodeRound =  new NodeRound(null,1,null);//哨兵

        nodeRound.prev = nodeRound;
        nodeRound.next = nodeRound;
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值