算法通关村第一关——链表青铜挑战笔记

1.单链表

链表由多个节点组成,每个节点包含两个部分:数据和指针部分。
链表的元素在内存中不是连续存储的,而是分散在内存中,每个节点只需要存储下一个节点的地址。
一个节点可以有多个前驱节点,但只能有一个后继节点。
单链表的第一个节点为头结点 head。
dummyNode 虚拟节点,作用是方便处理头结点,dummyNode.next=head。它val不会被使用,随便初始化即可。

2.Java创建单链表

public class BasicLink {

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5, 6};
        Node head = initLinkedList(a);
        System.out.println(head);
    }
    
    private static Node initLinkedList(int[] array) {
        Node head = null, cur = null;
        for (int i = 0; i < array.length; i++) {
            Node newNode = new Node(array[i]);
            if (i == 0) {
                head = newNode;
                cur = newNode;
            } else {
                cur.next = newNode;
                cur = newNode;
            }
        }
        return head;
    }
    
	static class Node {
	    public int val;
	    public Node next;
	
	    Node(int x) {
	        val = x;
	        next = null;
	    }
	}
}

算法通关村第一关——链表青铜挑战笔记_第1张图片
JVM有堆区和栈区,栈区主要存引用,即上图的course相当于head引用,而Node对象都存在堆区。
// 上面 Node 类中 val 和 next 成员变量设为 public,是为了能直接使用 node.val 和 node.next 操作,虽然违背面向对象的设计要求,但写法精简被广泛使用。

3.单链表的增删查改

插入new节点
<头插>:new.next=head;return new;
<中插>:如下图在7前面插入一个结点,那么应遍历到节点15,因为要进行 new.next=15.next,15.next=new 这两步(这两步顺序不能反,不然就找不到节点7了)。
算法通关村第一关——链表青铜挑战笔记_第2张图片
<尾插>:找到单链表最后一个节点last,last.next=new。
// 注意判断 head==null 的情况

// 获取链表长度
public static int getLength(Node head) {
    int length = 0;
    Node node = head;
    while (node != null) {
        length++;
        node = node.next;
    }
    return length;
}

public static Node insertNode(Node head, Node nodeInsert, int position) {
    // 判空
    if (head == null) {
        return nodeInsert;
    }
    // 越界判断
    int size = getLength(head);
    if (position > size + 1 || position < 1) {
        System.out.println("位置参数越界");
        return head;
    }

    // 头插
    if (position == 1) {
        nodeInsert.next = head;
        return nodeInsert;
    }

    Node pNode = head;
    int count = 1;
    while (count < position - 1) {
        pNode = pNode.next;
        count++;
    }
    nodeInsert.next = pNode.next;
    pNode.next = nodeInsert;
    return head;
}

删除节点
让目标节点 tar 变不可达(即没有节点指向目标节点),JVM就会自动回收。
<头删>:head=head.next;
<中删和尾删>:需要找到 tar 的前驱节点 prev,然后prev.next=tar.next;

public static Node deleteNode(Node head, int position) {
    if (head == null) {
        return null;
    }
    int size = getLength(head);
    if (position > size || position <= 0) {
        System.out.println("输入的参数有误");
        return head;
    }

    if (position == 1) {
        // head.next就是链表的新head
        return head.next;
    }
    
    Node preNode = head;
    int count = 1;
    while (count < position - 1) {
        preNode = preNode.next;
        count++;
        
    }
    Node curNode = preNode.next;
    preNode.next = curNode.next;
    return head;
}

4.双向链表

单链表定义时只有 next 指向下一个节点对象,双向链表即多了一个引用 prev 能指向节点的前驱节点。
算法通关村第一关——链表青铜挑战笔记_第3张图片

static class Node {
    public int val;
    public Node prev;
    public Node next;

    Node(int x) {
        val = x;
        prev = null;
        next = null;
    }
}

5.衍生出的数据结构

二叉树

static class Node {
    public int val;
    public Node left;
    public Node right;

    Node(int x) {
        val = x;
        left = null;
        right = null;
    }
}

多叉树

static class Node {
    public int val;
    public List<Node> children;

    Node(int x) {
        val = x;
    }
}

你可能感兴趣的:(算法与数据结构,算法,链表,笔记)