• 循环控制-链表反转(与创建链表)


    0.目录

    1.循环控制

    2.Java代码实现

    1.循环控制

    循环书写方法:

    • 定义循环不变式,并在循环体每次结束后保持循环不变式
    • 一般 ,后特殊
    • 每次 必须 向前推进循环不变式中涉及的变量值
    • 每次推进的规模必须为 1

    循环不表示(loop invariant):是一句断言定义各变量所满足的条件

    2.Java代码实现

    2.1 创建链表和递归反转实现

    前面已经写过递归的版本了,传送门:
    递归控制-链表反转

    本篇结点和创建链表的实现同前文 递归控制-创建链表

    2.2 循环反转思路

    1.先考虑循环中的某一个情况——循环到3时,应该要实现哪些操作?

    2.此时应该要把3 → 4的指针改为3 → 2,而4作为剩下的第一个结点。
    为了实现这一功能,加入两个指针newHead(指向反转成功的链表)和curHead(指向还没有反转的链表):

    3.所以每一次循环做的操作就是跟随两个指针往后移:

    4.总体来看就是用两个指针从头循环到尾一步步地反转链表:

    2.3 链表反转的实现

    依据反转思路实现循环代码即可。

        public Node reverseLinkedList(Node head) {
            Node newHead = null;
            Node curHead = head;
            // Loop invariant:
            // newHead points to the linked list already reversed.
            // curHead points to the linked list not yet reversed.
            while (curHead != null) {
                // Loop invariant holds.
                Node next = curHead.getNext();
                curHead.setNext(newHead);
                newHead = curHead;
                curHead = next;
                // Loop invariant holds.
            }
            // Loop invariant holds.
            return newHead;
        }
    

    ps:不需要在开头处理:if(head = null),程序也能够很好的处理特殊情况。

    验证在循环最后一步时程序的正确性:

            while (curHead != null) {
                // Loop invariant holds.
                Node next = curHead.getNext();    // next = null
                curHead.setNext(newHead);         // curHead.next reversed
                newHead = curHead;                // newHead points to last
                curHead = next;                   // curHead = null
                // Loop invariant holds.
            }
    

    2.4 测试用例

    测试程序是否正确运行(采用之前递归实现的测试用例):

        public static void main(String[] args) {
            LinkedListCreator creator = new LinkedListCreator();
            LinkedListReverser reverser = new LinkedListReverser();
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(new ArrayList<>())));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(Arrays.asList(1))));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(Arrays.asList(1, 2, 3, 4, 5))));
        }
    

    运行结果为

    main所在java文件全部代码:

    import java.util.ArrayList;
    import java.util.Arrays;
    
    import interview.common.Node;
    import interview.recursion.LinkedListCreator;
    
    public class LinkedListReverser {
    
        public Node reverseLinkedList(Node head) {
            Node newHead = null;
            Node curHead = head;
            // Loop invariant:
            // newHead points to the linked list already reversed.
            // curHead points to the linked list not yet reversed.
            while (curHead != null) {
                // Loop invariant holds.
                Node next = curHead.getNext();
                curHead.setNext(newHead);
                newHead = curHead;
                curHead = next;
                // Loop invariant holds.
            }
            // Loop invariant holds.
            return newHead;
        }
    
        public static void main(String[] args) {
            LinkedListCreator creator = new LinkedListCreator();
            interview.recursion.LinkedListReverser reverser = new interview.recursion.LinkedListReverser();
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(new ArrayList<>())));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(Arrays.asList(1))));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(Arrays.asList(1, 2, 3, 4, 5))));
        }
    }
    

    2.5 循环控制-创建链表

    最后再把创建链表的递归实现也改为循环实现:

        public Node createLargeLinkedList(int size) {
            Node prev = null;
            Node head = null;
            for (int i = 1; i <= size; i++) {
                Node node = new Node(i);
                if (prev != null) {
                    prev.setNext(node);
                } else {
                    head = node;
                }
                prev = node;
            }
            return head;
        }
    

    测试一下:

        public static void main(String[] args) {
            LinkedListCreator creator = new LinkedListCreator();
            interview.recursion.LinkedListReverser reverser = new interview.recursion.LinkedListReverser();
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(new ArrayList<>())));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(Arrays.asList(1))));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLinkedList(Arrays.asList(1, 2, 3, 4, 5))));
    
            Node.printLinkedList(reverser.reverseLinkedList(
                creator.createLargeLinkedList(100)));
        }
    

    运行结果:

  • 相关阅读:
    Unity 历史版本的安装
    jQuery使用记录
    tkinter 按钮响应函数传值
    python网络爬虫入门(二)
    python 爬取豆瓣书籍信息
    python 爬取猫眼电影top100数据
    SpringMVC+SpringBoot+MyBatis
    时间日期类
    Mybatis框架(三)
    Java框架之MyBatis框架(二)
  • 原文地址:https://www.cnblogs.com/PyLearn/p/10039206.html
Copyright © 2020-2023  润新知