Java实现链表的增加,删除,打印

Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。

说明:以下代码是按照自己理解实现,有不正确的地方,请批评指正!!

1. 定义结点类

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

2. 建表(尾插法)

思路:
头插法建立链表虽然算法简单,但生成的链表中结点的次序和输入的顺序相反。若希望二者次序一致,可采用尾插法建表。该方法是将新结点插入到当前链表的表尾上,为此必须增加一个尾指针tail,使其始终指向当前链表的尾结点。
// 1. 创建单链表(尾插法建表)
    public static ListNode createList(int[] arr)
    {
        ListNode head = new ListNode(arr[0]); // 头结点
        ListNode tail = head;
        for (int i = 1; i < arr.length; i++)
        {
            ListNode newNode = new ListNode(arr[i]);
            tail.next = newNode;
            tail = newNode;
        }
        return head;
    }

3. 打印链表

// 2. 打印链表
    public static void printList(ListNode head)
    {
        while (head != null)
        {
            if (head.next == null)
                System.out.println(head.val);
            else
                System.out.print(head.val + " --> ");

            head = head.next;
        }
    }
// 输出结果: 11 --> 22 --> 33 --> 44 --> 55

4. 插入结点

	// 3. 在建好的链表中的第k个位置插入一个值为val的结点
   public static ListNode insertNode(ListNode head, int k, int val)
    {
        ListNode preNode = head; // 临时指针,用于指向要插入位置的前一个结点

        if (k < 1)
            return head;
        if (k == 1) // 如果在第一个位置插入(将插在第1个结点之前)
        {
            ListNode newNode = new ListNode(val); // 创建该结点
            newNode.next = preNode;
            head = newNode;

            return head;
        }

        while (k-- > 2) // 使preNode指向第k个位置的前一个结点
        {
            preNode = preNode.next;
        }

        ListNode newNode = new ListNode(val); // 创建该新结点
        // 插入
        newNode.next = preNode.next;
        preNode.next = newNode;

        return head;
    }

5. 删除结点

// 4. 删除结点(删除第k个结点)
 public static ListNode delNode(ListNode head, int k)
    {
        ListNode preNode = head; // 临时指针,用于指向要删除位置的前一个结点

        if (k < 1) // 不删任何结点
            return head;
        if (k == 1) // 删除第一个结点
        {
            head = head.next; // 将指针往后移动一位就相当于删除了第一个结点
            return head;
        }

        while (k-- > 2) // 使preNode指向第k个结点的前面一个结点
        {
            preNode = preNode.next;
        }
        // 删除结点(通过跳过待删除结点来实现删除结点的效果)
        preNode.next = preNode.next.next;

        return head;
    }

6. 总代码

class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}

public class Main {
    public static void main(String[] args) {

        int[] arr = {11, 22, 33, 44, 55};
        ListNode head = createList(arr); // 建表

        // 打印链表
        printList(head);

        // 插入
//        //head = insertNode(head, 1, 99); // 在第一个位置插入99
//        head = insertNode(head, 3, 99);  // 在第3个位置插入99
//        printList(head);

        // 删除
        head = delNode(head, 2);  // 删除地2个结点
        printList(head);


    }

    // 1. 创建带头结点的单链表(尾插法建表)
    public static ListNode createList(int[] arr)
    {
        ListNode head = new ListNode(arr[0]); // 头结点
        ListNode tail = head;
        for (int i = 1; i < arr.length; i++)
        {
            ListNode newNode = new ListNode(arr[i]);
            tail.next = newNode;
            tail = newNode;
        }
        return head;
    }

    // 2. 打印链表
    public static void printList(ListNode head)
    {
        while (head != null)
        {
            if (head.next == null)
                System.out.println(head.val);
            else
                System.out.print(head.val + " --> ");

            head = head.next;
        }
    }


    // 3. 在建好的链表中的第k个位置插入一个值为val的结点
    public static ListNode insertNode(ListNode head, int k, int val)
    {
        ListNode preNode = head; // 临时指针,用于指向要插入位置的前一个结点

        if (k < 1)
            return head;
        if (k == 1) // 如果在第一个位置插入(将插在第1个结点之前)
        {
            ListNode newNode = new ListNode(val); // 创建该结点
            newNode.next = preNode;
            head = newNode;

            return head;
        }

        while (k-- > 2) // 使preNode指向第k个位置的前一个结点
        {
            preNode = preNode.next;
        }

        ListNode newNode = new ListNode(val); // 创建该新结点
        // 插入
        newNode.next = preNode.next;
        preNode.next = newNode;

        return head;
    }


    // 4. 删除结点(删除第k个结点)
    public static ListNode delNode(ListNode head, int k)
    {
        ListNode preNode = head; // 临时指针,用于指向要删除位置的前一个结点

        if (k < 1) // 不删任何结点
            return head;
        if (k == 1) // 删除第一个结点
        {
            head = head.next; // 将指针往后移动一位就相当于删除了第一个结点
            return head;
        }

        while (k-- > 2) // 使preNode指向第k个结点的前面一个结点
        {
            preNode = preNode.next;
        }
        // 删除结点(通过跳过待删除结点来实现删除结点的效果)
        preNode.next = preNode.next.next;

        return head;
    }

}
posted @ 2019-10-07 16:21  helloHKTK  阅读(2175)  评论(0编辑  收藏  举报