Loading

链表(单向)

基本介绍

链表是有序列表,但是在内存中是存储如下。

如上图:

1)链表是以节点的方式来存储,是链式存储。
2)每个节点包含data域,next域:指向下一个节点。
3)链表的各个节点不一定是连续存储。
4)链表分带头节点的链表和没有头节点的链表。

单链表(带头节点)逻辑结构示意图如下

增删改查

节点类

package com.linkedlist.test;

public class Node {
    public int no;
    public String name;
    public Node next;
    public Node(int no,String name){
        this.no = no;
        this.name = name;
    }
    public Node(){};

    @Override
    public String toString() {
        return "Node{" +
                "no=" + no +
                ", name='" + name +
                '}';
    }
}

方法一:

先创建一个head头节点。
后面每添加一个节点,就直接加入到链表的最后。
通过一个辅助节点变量,帮助遍历整个链表。
    public void add(Node node){
        Node temp = head;
        while(true){
            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }
        temp.next = node;
    }

方法二:

根据编号的顺序添加:
    首先找到新添加节点的位置,通过辅助节点完成添加
    public void addOrderByAsc(Node node){
        Node temp = head;
        boolean flag = false;
        while(true){
            if(temp.next == null){
                break;
            }
            if(temp.next.no > node.no){
                break;
            }else if(temp.next.no == node.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            System.out.println("节点已经存在!");
        }else{
            node.next = temp.next;
            temp.next = node;
        }
    }

先找到需要删除节点的前一个节点temp;
temp.next = temp.next.next;
被删除的节点,将不会有其他引用指向,会被垃圾回收机制回收;
    public void del(int no){
        boolean flag = false;
        Node temp = head;
        while(true){
            if(temp.next == null){
                break;
            }
            if(temp.next.no == no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.next = temp.next.next;
        }else{
            System.out.println("未找到该节点!");
        }
    }

通过遍历找到要修改的节点进行修改
    public void update(Node node){
        if(head.next == null){
            System.out.println("链表为空!");
            return;
        }
        boolean flag = false;
        Node temp = head.next;
        while(true){
            if(temp == null){
                break;
            }
            if(temp.no == node.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.name = node.name;
        }else{
            System.out.println("未找到该节点!");
        }
    }

其他操作

  1. 获取链表有效节点个数。
    public int getLength(){
        int length = 0;
        Node temp = head;
        while(true){
            if(temp.next == null){
                break;
            }
            length++;
            temp = temp.next;
        }
        return length;
    }
  1. 获取倒数第n个节点
    public Node getLastNode(int n){
        if( n <= 0 || n > getLength()){
            return null;
        }
        Node temp = head.next;
        for (int i = 0; i < getLength() - n; i++) {
            temp = temp.next;
        }
        return temp;
    }
  1. 反转链表
    public void reverseLinkedList(){
        if(head.next == null || head.next.next == null){
            return;
        }
        Node cur = head.next;
        Node next = null; //指向当前节点的下一个节点
        Node reverseHead = new Node();

        //遍历原来的链表,每遍历一个节点,就将其取出放在reverseHead的最前端
        while(cur != null){
            next = cur.next;  //暂时保存当前节点的下一个节点
            cur.next = reverseHead.next; //将cur的下一个节点指向新的链表的最前端
            reverseHead.next = cur;  //将cur连接到新链表上
            cur = next; //后移
        }

        head.next = reverseHead.next;
    }
  1. 逆序打印
    public void reversePrint(){
        Stack<Node> stack = new Stack<Node>();
        Node cur = head.next;
        while(cur != null){
            stack.push(cur);
            cur = cur.next;
        }
        while(stack.size() > 0){
            System.out.println(stack.pop());
        }

    }
posted @ 2021-11-03 16:22  IamHzc  阅读(36)  评论(0编辑  收藏  举报