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

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)));
    }

运行结果:

posted @ 2018-11-29 16:29  PyLearn  阅读(448)  评论(0编辑  收藏  举报