3

I'm doing some homework problems, and I'm getting stumped on a couple. I'm having a hard time understanding the best methods to swap data in a list.

I'm supposed to make the method reverse() and it uses the LinkedIntList class (below). It's a limited list class, so I can only use what's there.

The point is to take a list of items

[1, 2, 3, 4, 5] and reverse them [5, 4, 3, 2, 1]

I thought my pseudo code would be

take the first piece of data and append it to the list. loop over the original size(since that changes) and take out the piece at 0 then add the current piece at 0, 1 position behind the end.

for an input like this: [1, 8, 19, 4, 17]
expected is this: front -> [17] -> [4] -> [19] -> [8] -> [1] /
my code gets this: front -> [19] -> [4] -> [17] -> [8] -> [19] -> [1] /

Not sure what I'm doing wrong.

public void reverse(){
    int x = this.size();
    this.add(front.data);

    for (int i = 0; i < x; i++){
                this.remove(0);
        this.add(this.size()-1, front.data);
    }
}

// A LinkedIntList object can be used to store a list of integers.
public class LinkedIntList {
    private ListNode front;   // node holding first value in list (null if empty)
    private String name = "front";   // string to print for front of list

    // Constructs an empty list.
    public LinkedIntList() {
        front = null;
    }

    // Constructs a list containing the given elements.
    // For quick initialization via Practice-It test cases.
    public LinkedIntList(int... elements) {
        this("front", elements);
    }

    public LinkedIntList(String name, int... elements) {
        this.name = name;
        if (elements.length > 0) {
            front = new ListNode(elements[0]);
            ListNode current = front;
            for (int i = 1; i < elements.length; i++) {
                current.next = new ListNode(elements[i]);
                current = current.next;
            }
        }
    }

    // Constructs a list containing the given front node.
    // For quick initialization via Practice-It ListNode test cases.
    private LinkedIntList(String name, ListNode front) {
        this.name  = name;
        this.front = front;
    }

    // Appends the given value to the end of the list.
    public void add(int value) {
        if (front == null) {
            front = new ListNode(value, front);
        } else {
            ListNode current = front;
            while (current.next != null) {
                current = current.next;
            } 
            current.next = new ListNode(value);
        }
    }

    // Inserts the given value at the given index in the list.
    // Precondition: 0 <= index <= size
    public void add(int index, int value) {
        if (index == 0) {
            front = new ListNode(value, front);
        } else {
            ListNode current = front;
            for (int i = 0; i < index - 1; i++) {
                current = current.next;
            } 
            current.next = new ListNode(value, current.next);
        }
    }

    public boolean equals(Object o) {
        if (o instanceof LinkedIntList) {
            LinkedIntList other = (LinkedIntList) o;
            return toString().equals(other.toString());   // hackish
        } else {
            return false;
        }
    }

    // Returns the integer at the given index in the list.
    // Precondition: 0 <= index < size
    public int get(int index) {
        ListNode current = front;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        return current.data;
    }

    // Removes the value at the given index from the list.
    // Precondition: 0 <= index < size
    public void remove(int index) {
        if (index == 0) {
            front = front.next;
        } else {
            ListNode current = front;
            for (int i = 0; i < index - 1; i++) {
                current = current.next;
            }
            current.next = current.next.next;
        }
    }

    // Returns the number of elements in the list.
    public int size() {
        int count = 0;
        ListNode current = front;
        while (current != null) {
            count++;
            current = current.next;
        }
        return count;
    }

    // Returns a text representation of the list, giving
    // indications as to the nodes and link structure of the list.
    // Detects student bugs where the student has inserted a cycle
    // into the list.
    public String toFormattedString() {
        ListNode.clearCycleData();

        String result = this.name;

        ListNode current = front;
        boolean cycle = false;
        while (current != null) {
            result += " -> [" + current.data + "]";
            if (current.cycle) {
                result += " (cycle!)";
                cycle = true;
                break;
            }
            current = current.__gotoNext();
        }

        if (!cycle) {
            result += " /";
        }

        return result;
    }

    // Returns a text representation of the list.
    public String toString() {
        return toFormattedString();
    }

    // Returns a shorter, more "java.util.LinkedList"-like text representation of the list.
    public String toStringShort() {
        ListNode.clearCycleData();

        String result = "[";

        ListNode current = front;
        boolean cycle = false;
        while (current != null) {
            if (result.length() > 1) {
                result += ", ";
            }
            result += current.data;
            if (current.cycle) {
                result += " (cycle!)";
                cycle = true;
                break;
            }
            current = current.__gotoNext();
        }

        if (!cycle) {
            result += "]";
        }

        return result;
    }


    // ListNode is a class for storing a single node of a linked list.  This
    // node class is for a list of integer values.
    // Most of the icky code is related to the task of figuring out
    // if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part.

    public static class ListNode {
        private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>();

        public static void clearCycleData() {
            for (ListNode node : ALL_NODES) {
                node.visited = false;
                node.cycle = false;
            }
        }

        public int data;          // data stored in this node
        public ListNode next;     // link to next node in the list
        public boolean visited;   // has this node been seen yet?
        public boolean cycle;     // is there a cycle at this node?

        // post: constructs a node with data 0 and null link
        public ListNode() {
            this(0, null);
        }

        // post: constructs a node with given data and null link
        public ListNode(int data) {
            this(data, null);
        }

        // post: constructs a node with given data and given link
        public ListNode(int data, ListNode next) {
            ALL_NODES.add(this);
            this.data = data;
            this.next = next;
            this.visited = false;
            this.cycle = false;
        }

        public ListNode __gotoNext() {
            return __gotoNext(true);
        }

        public ListNode __gotoNext(boolean checkForCycle) {
            if (checkForCycle) {
                visited = true;

                if (next != null) {
                    if (next.visited) {
                        // throw new IllegalStateException("cycle detected in list");
                        next.cycle = true;
                    }
                    next.visited = true;
                }
            }
            return next;
        }
    }

// YOUR CODE GOES HERE

}
4

3 回答 3

2

这是带有打印语句的代码:

public void reverse() {
  System.out.println(toFormattedString());

  int x = this.size();
  this.add(front.data);
  System.out.println(toFormattedString());

  for (int i = 0; i < x; i++) {
    this.remove(0);
    System.out.println(toFormattedString());
    this.add(this.size() - 1, front.data);
    System.out.println(toFormattedString());
  }
}

输出:

front -> [1] -> [2] -> [3] -> [4] -> [5] /
front -> [1] -> [2] -> [3] -> [4] -> [5] -> [1] /
front -> [2] -> [3] -> [4] -> [5] -> [1] /
front -> [2] -> [3] -> [4] -> [5] -> [2] -> [1] /
front -> [3] -> [4] -> [5] -> [2] -> [1] /
front -> [3] -> [4] -> [5] -> [2] -> [3] -> [1] /
front -> [4] -> [5] -> [2] -> [3] -> [1] /
front -> [4] -> [5] -> [2] -> [3] -> [4] -> [1] /
front -> [5] -> [2] -> [3] -> [4] -> [1] /
front -> [5] -> [2] -> [3] -> [4] -> [5] -> [1] /
front -> [2] -> [3] -> [4] -> [5] -> [1] /
front -> [2] -> [3] -> [4] -> [5] -> [2] -> [1] /

希望这可以帮助。

于 2012-08-02T07:32:13.910 回答
1

首先,您应该获取第一个元素并将其添加到 (xi) 的索引中。然后删除第一个元素。我的意思是你的循环应该是;

for (int i = 0; i < x; i++){

    this.add(this.size()-i, front.data);
    this.remove(0);
}

你也可以删除它;

this.add(front.data);

我认为这有帮助。

于 2012-08-02T11:21:47.357 回答
1

嗨,您总是向您提供数据,size()-1您可能想要这样做

this.add(this.size()-i-1, front.data);

然后再次删除第一个元素。

不要犹豫,一步一步调试你的代码,看看它是如何运行的。


在网站上不应该阻止您使用 IDE,但a piece of paper也可以完成工作。

于 2012-08-02T07:10:02.560 回答