看一下链表结构

序、慢慢来才是最快的方法。

背景

链表(Linked List)
链表是一种常见的基础数据结构,是一种线性表。与顺序表不同的是,链表中的每个节点不是顺序存储的,而是通过节点的指针域指向到下一个节点。

1.链表的优缺点

看一下链表结构_第1张图片

2.链表的类型

单链表、双链表、循环链表、静态链表。

1.单链表

  • element:用来存放元素
  • next:用来指向下一个节点元素
  • 通过每个结点的指针指向下一个结点从而链接起来的结构,最后一个节点的next指向null。

看一下链表结构_第2张图片

代码示例:

//单向链表
class SingleLinkedList{

    //先初始化一个头节点, 头节点不要动, 不存放具体的数据
    private Node head = new Node("");

    //添加节点
    public void add(Node node){
        Node temp = head;
        while (true){
            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }
        temp.next = node;
    }

    // 插入新节点到链表的头部  
    public void insertAtHead(String data) {  
        Node newNode = new Node(data);  
        if (head != null) {  
            //新链表的next直接指向head即可。
            newNode.next = head;  
        }  
        head = newNode;  
    }  


    //删除节点
    public void del(String element) throws Exception {
        Node temp = head;
        boolean flag = false; // 标志是否找到待删除节点的

        while (true){
            if(temp.next == null){//最后一个节点
                break;
            }
            if(temp.next.element == element){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if(flag){
            temp.next = temp.next.next;
        } else {
            throw new Exception("没有找到要删除的节点");
        }
    }
    
    //定义节点
    class Node{
        public String element;//用来存放元素
        public Node next; //指向下一个节点
        
        public Node(String element) {
            super();
            this.element = element;
        }
    }
}

单链表反转

反转链表问题在面试中出现频率 非常非常高,相信有过几次面试经验的同学都会同意这个观点。

解法1:递归
  //递归解法
    private Node reversetList(Node node) {
        if (node == null || node.next == null) {
            return head;
        }

        Node nodePre= reversetList(node);
        node.next.next = node.next;
        node.next = null;

        return nodePre;
    }
解法2:迭代
   //单链表反转 迭代
    private Node reversetList1(Node node) {
        //如果当前链表为null,或者只有一个节点,则无需反转
        if (node == null && node.next == null) {
            return node;
        }

        //定义一个辅助的指针(变量),帮助我们遍历原来的链表
        Node cur = node.next;
        Node next = null;// 指向当前节点[cur]的下一个节点
        Node reverseNode = new Node("");

        while (cur != null) {
            next = cur.next;//先暂时保存当前节点的下一个节点,因为后面需要使用
            cur.next = reverseNode.next;///将cur 的下一个节点指向新的链表的最前端
            reverseNode = cur;将cur 连接到新的链表上
            cur = next;//让cur 后移
        }

        return reverseNode;
    }

2.双链表

单向链表的好处很多,虽然单链表能 100% 解决逻辑关系为 "一对一" 数据的存储问题,但在解决某些特殊问题时,单链表并不是效率最优的存储结构。比如说,如果算法中需要大量地找某指定结点的前趋结点,使用单链表无疑是灾难性的,因为单链表更适合 "从前往后" 找,而 "从后往前" 找并不是它的强项,因此我们就有了双向链表这个东西,双向链表顾名思义就是链表的高级版,他与单向链表有所不同的一点在于在具有尾巴结点,并且双向链表的每一个结点都会有两个指向,一个指向前面的结点,一个指向后面的结点,当然头结点的前端指向为null,后结点的后端指向为null。
 

element、pre、next 跟前面的一样。

第一个节点的pre指向最后一个节点,最后一个节点的next指向第一个节点,形成一个环。

看一下链表结构_第3张图片

代码示例

public ListNode head;
    public ListNode last;
    public TowWayNodeList(int num){
        this.head = new ListNode(num);
        this.last = this.head;
    }


//头插法
    public void addFirst(int num){
        ListNode node = new ListNode(num);
        if(head == null){
            this.head = node;
            this.last = node;
        }else{
            node.next = this.head;
            this.head.prev = node;
            this.head = node;
        }
    }


//尾插发
public void addLast(int data){
        ListNode node = new ListNode(data);
        if(head == null){
            this.head = node;
            this.last = node;
        }else{
            this.last.next = node;
            node.prev = this.last;
            this.last = node;
        }
    }

参考

数据结构与算法 #1 链表问题总结 - 掘金

leetcode 206 号算法题:反转单链表【数据结构与算法】_哔哩哔哩_bilibili

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

Java实现双向链表_双向链表java实现_跑不死的程序员的博客-CSDN博客

你可能感兴趣的:(链表,数据结构)