【习题解答】数据结构与算法分析-Java语言描述 第三版 —— 第三章 表、栈、队列

397 阅读2分钟

写作起因

最近因为找工作因为算法碰了不少壁。深感自己对算法的缺陷,于是买了《数据结构与算法分析-Java语言描述 第三版》复习一下自己的薄弱的算法基础。

结果做完题的时候,居然找不到一个像样的答案。这就很苦恼了。

Pearson官网必须要有教师资格证才能拿到答案。国内的出版社貌似也一样。既然没有,那就由我来为中文程序猿社区做点贡献吧。

不敢说全对,大体是没问题的。欢迎大家斧正。

3.1

给定一个表L和另一个表P,它们包含以升序排列的整数。操作printLots(L,P)将打印L中那些由P所指定的位置上的元素。例如,如果P=1,3,4,6,那么,L中位于第1、第3、第4和第6个位置上的元素被打印出来。写出过程printLots(L,P)。只可使用public型的Collections API容器操作。该过程的运行时间是多少?

根据题意,L存数据,P存L的下标,然后打印下标对应的元素。要求必须用Collections API来操作。 我特地去看了一下Collections的API,完全无法实现这个操作。看了第二版的题解(题在第二版是一样的),结果用的是List来当容器。好嘛,原来用的是Collection的API。(捂脸)

关于运行时间,应该说的是时间复杂度。

若L长为m,P长为n,那么时间复杂度为:O(m+n)

代码如下

import java.util.*;

public class ThreeOne {
    public static void main(String[] args) {
        Character[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
                'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
        Integer[] idxs = {1, 4, 7, 10, 17, 25};

        ArrayList<Character> L = new ArrayList<Character>(Arrays.asList(chars));
        ArrayList<Integer> P = new ArrayList<Integer>(Arrays.asList(idxs));

        long startTime = System.nanoTime();
        System.out.println("startTime = " + startTime + "nanosec");
        printLots(L, P);
        long endTime = System.nanoTime();
        System.out.println("endTime = " + endTime + "nanosec");
        System.out.println("Duration: " + (endTime - startTime) + " nanosec or " + (endTime - startTime) / 1e6 + " milisec");
    }
    
    public static <T> void printLots(Collection<T> L, Collection<Integer> P) {
        Iterator iterP = P.iterator();
        Iterator iterL = L.iterator();
        int idxL = 0;
        T itemL = null;
        while (iterP.hasNext() && iterL.hasNext()) {
            int idx = (int) iterP.next();
            while (iterL.hasNext() && idxL < idx) {
                itemL = (T) iterL.next();
                idxL++;
            }
            System.out.print(itemL + " ");
        }
        System.out.println();
    }
}

3.2

通过只调整链(而不是数据)来交换两个相邻的元素,使用 a.单链表。 b.双链表。

很明显,这题要使用链表来实现。

代码如下

//For convenience, use double linked node as singly linked node.
class Node {
    int value;
    Node pre;
    Node next;
}

public class ThreeTwo {
    /**
     * @param before the node before the two nodes to be swapped.
     */
    public static void swapNodes(Node before) {
        if (before == null || (before != null && before.next == null) || (before != null && before.next != null && before.next.next == null)) {
            throw new IllegalArgumentException("There are no nodes to swap.");
        }
        Node first = before.next;
        Node second = first.next;

        before.next = second;
        first.next = second.next;
        second.next = first;
    }

    /**
     * @param first the first node to be swapped.
     */
    public static void swapNodesD(Node first) {
        if (first == null || (first != null && first.next == null)) {
            throw new IllegalArgumentException("There are no nodes to swap.");
        }

        Node second = first.next;

        first.pre.next = second;
        first.next = second.next;
        second.pre = first.pre;
        first.pre = second;
        second.next = first;
    }

    /**
     * Main
     *
     * @param args
     */
    public static void main(String[] args) {
        Node dummyHead = new Node();
        Node cur = dummyHead;

        for (int i = 0; i < 10; i++) {
            cur.next = new Node();
            cur.next.pre = cur;
            cur.next.value = i;
            cur = cur.next;
        }

        //swap 3 with 4
        Node n = dummyHead.next.next.next;
        swapNodes(n);
        //swap 6 with 7
        n = n.next.next.next.next;
        swapNodesD(n);

        Node p = dummyHead.next;
        while (p != null) {
            System.out.print(p.value + " ");
            p = p.next;
        }
    }
}

持续更新中...