数据结构——链表

目录

1.链表

2.节点实现(内部类)

3.列表基本成员

4.增删改查

4.1增加

4.1.1改进 虚拟头节点

4.2查询

4.3修改链表中某处的元素

4.4  删除操作

4.4.1 根据索引删除元素

4.4.2 根据元素删除元素

5 遍历操作 



1.链表

链表是线性表最常见的两种表现方式之一

数据储存在节点(Node)中 Node一般来说包括:元素、前驱、后继

第一个节点的前驱是null,最后一个节点的后继是null

真正地实现了动态,不需要考虑动态扩容的问题

2.节点实现(内部类)


public class LinkList<E> {
    private class Node {
        //元素
        public E e;
        //节点
        public Node next;

        //指定元素与下一个节点的构造器
        public Node(E e, Node next) {
            this.e = e;
            this.next = next;
        }

        public Node(E e) {
            this(e, null);//指定元素下一个节点为null
        }

        public Node() {
            this(null, null);//空构造器,元素与下一个节点均为null
        }

        @Override
        public String toString() {
            return e.toString();
        }
    }
}

3.列表基本成员

  • 头节点
  • 元素数量
    
    
        private Node head;//头节点
        private int size;//元素数量
    
        public LinkList() {//构造函数
            head = null;
            size = 0;
        }
    
        public int getSize() {
            return size;//获得元素数量
        }
    
        public boolean isEmpty() {
            return size == 0;
        }
    }
    

    4.增删改查

  • 4.1增加

  •   public void addFirst(E e){//在头部添加
            //将元素放进新生成的节点中
            Node node = new Node(e);
            //将新节点指向现在的头部
            node.next=head;
            //将头节点换成新节点
            head=node;
        }

        public void add(int index, E e) {
            if (index < 0 || index > size) {
                throw new IllegalArgumentException("参数不合法,添加失败");
            }
            if (index == 0) {
                addFirst(e);
            } else {
                Node prev = head;
                for (int i = 0; i < index - 1; i++) {
                    prev = prev.next;
                }
                Node node = new Node(e);
                node.next = prev.next;
                prev.next = node;
                size++;
            }
        }

    public void addLast(E e) {
            add(size, e);
        }

    4.1.1改进 虚拟头节点

  • 由于在头部添加时,无前一个,所以产生了虚拟头节点
  • 虚拟头节点的元素是null,指向了实际的头一个节点
  • package Array;
    
    public class LinkList<E> {
        //节点内部类   1.链表是由节点串起来的2.下一个节点应该作为引用
        private class Node {
            //元素
            public E e;
            //节点
            public Node next;
    
            //指定元素与下一个节点的构造器
            public Node(E e, Node next) {
                this.e = e;
                this.next = next;
            }
    
            public Node(E e) {
                this(e, null);//指定元素下一个节点为null
            }
    
            public Node() {
                this(null, null);//空构造器,元素与下一个节点均为null
            }
    
            @Override
            public String toString() {
                return e.toString();
            }
        }
    
        private Node visualHead;//头节点
        private int size;//元素数量
    
        public LinkList() {//构造函数
            visualHead = new Node();
            size = 0;
        }
    
        public int getSize() {
            return size;//获得元素数量
        }
    
        public boolean isEmpty() {
            return size == 0;
        }
    
        public void addFirst(E e) {
    //        //将元素放进新生成的节点中
    //        Node node = new Node(e);
    //        //将新节点指向现在的头部
    //        node.next = head;
    //        //将头节点换成新节点
    //        head = node;
            add(0,e);
        }
    
        public void add(int index, E e) {
    //        if (index < 0 || index > size) {
    //            throw new IllegalArgumentException("参数不合法,添加失败");
    //        }
            if (index == 0) {
                addFirst(e);
            } else {
                Node prev = visualHead;
                for (int i = 0; i < index - 1; i++) {
                    prev = prev.next;
                }
                Node node = new Node(e);
                node.next = prev.next;
                prev.next = node;
                size++;
            }
        }
    
        public void addLast(E e) {
            add(size, e);
        }
    

    4.2查询

    public E get(int index){ //根据索引查找元素
            if (index < 0 || index > size) {
                throw new IllegalArgumentException("参数不合法,查找失败");
            }
            Node current=visualHead.next;
            for (int i = 0; i < index; i++) {
                current=current.next;
            }return current.e;
        }

    4.3修改链表中某处的元素

     public void set(int index, E e) {
            if (index < 0 || index >= size) {
                throw new IllegalArgumentException("参数不合法,修改失败");
            }
            Node current = visualHead.next;
            for (int i = 0; i < index; i++) {
                current = current.next;
    
            }
            current.e = e;
        }

    4.4  删除操作

4.4.1 根据索引删除元素

//根据索引删除元素
public E remove(int index) {
//参数的合法性判断
if (index < 0 || index >= size) {
throw new IllegalArgumentException("删除失败,索引不合法");
}
//从虚拟头节点开始查找待删除节点的前一个
Node prev = visualHead;
//开始查找
for (int i = 0; i < index; i++) {
prev = prev.next;
}
//待删除节点
Node retNode = prev.next;
//删除操作
//待删除节点的前一个指向待删除结点的下一个
prev.next = retNode.next;

retNode.next = null;
size--;
//返回待删除节点的元素
return retNode.e;
}

//删除链表中第一个元素
public E removeFirst() {
return remove(0);
}
//删除链表中最后一个元素
public E removeLast() {
return remove(size - 1);
}

4.4.2 根据元素删除元素

//根据元素删除元素
public void removeElement(E e) {
//从虚拟头节点作为待删除节点的前一个
Node prev = visualHead;
//通过while循环找到待删除元素所在节点
while (prev.next != null) {
//判断下一个的节点元素值与参数是否一致
if (prev.next.e.equals(e)) {
//跳出循环,执行接下来的操作
break;
}
//prev向后传递
prev = prev.next;
}
Node retNode = prev.next;
prev.next = retNode.next;
retNode.next = null;
size--;
}

5 遍历操作 

  •     @Override
        public String toString() {
            StringBuilder res = new StringBuilder();
            Node current = visualHead.next;//从第一个实际结点出发进行遍历,虚拟头节点的下一个
    //        在链表结束之前做以下操作
            while (current != null) {
                res.append(current + "->");//加上箭头形象化链表
                current = current.next;//往后传递
            }
            res.append("null");//表示链表结束
            return res.toString();
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值