简体   繁体   中英

Java Doubly Linked List removeLast()

I have a class assignment that required me to create a class DoubleList that implements a ListADT.

I've gotten to the point where the code ALMOST works correctly. The output for the code should be: 1 3 7 9 13 14 16 17 23 24
3 9 13 16

My output is: 1 3 7 9 13 14 16 17 23 24
3 9 13 16 23

The first removeLast() seems to remove the 24 but for some reason the 23 stays after the second removeLast() is called. Please help!

EDIT: If I call removeLast() another time, it removes the 23.

class DoubleList<T> implements ListADT<T>{

    private int _size;
    private DoubleNode _head;
    private DoubleNode _tail;

    public DoubleList() {
        _size = 0;
        _head = null;
        _tail = null;
    }

    public T removeFirst(){
        if(_size == 0){
            return null;
        }
        DoubleNode tmp = _head;
        _head = _head._next;
        _head._previous = null;
        _size--;
        return tmp._value;
    }

    public T removeLast(){
        if(_size == 0) {
            return null;
        }
        T temp = _tail._value;
        _tail = _tail._previous;
        _tail._next = null;
        _size--;
        return temp;
    }

    public T remove(T element){
        if(_size == 0){
            return null;
        }

        DoubleNode current = _head;
        DoubleNode previous = null;
        T temp = null;

        do{
            if(current._value == element){
                temp = current._value;
                if(previous == null){
                    _head = _head._next;
                    _head._previous = null;
                }
                else{
                    previous._next = current._next;
                }
            }
            previous = current;
            current = current._next;
        }while(current != null);
        return temp;
    }

    public T first(){
        return _head._value;
    }

    public T last(){
        return _tail._value;
    }

    public boolean contains(T target){
        if(_size == 0){
            return false;
        }

        DoubleNode temp = _head;

        do{
            if(temp._value == target){
                return true;
            }
            temp = temp._next;
        }while(temp != null);
        return false;
    }

    public boolean isEmpty(){
        if(_size == 0){
            return true;
        }
        return false;
    }

    public int size(){
        return _size;
    }

    public void add(T element)
    {
        int add = 0;
        DoubleNode temp = new DoubleNode();
        temp._value = element;
        DoubleNode point = _head;
        DoubleNode placeHolder;

        if(_head == null) {
            _head = temp;
            _tail = temp;
            _size++;
            return;
        }
        else if((Integer)element <= (Integer)_head._value){
            temp._next = _head;
            _head._previous = temp;
            _head = temp;
            _size++;
            return;
        }

        do {

            if(point._next == null){
                point._next = temp;
                temp._previous = point;
                _tail = temp;
                _size++;
                return;
            }
            else if((Integer)point._next._value >= (Integer)element && (Integer)point._value < (Integer)element){
                placeHolder = point._next;
                point._next = temp;
                placeHolder._previous = temp;
                temp._next = placeHolder;
                temp._previous = point;
                _size++;
                return;
            }

            point = point._next;

        } while (point != null);


        _size++;
    }

    public String toString(){
        String returnString = "";
        if(_size == 0){
            return returnString;
        }

        DoubleNode temp = _head;

        do{
            returnString += temp._value + " ";
            temp = temp._next;
        }while(temp != null);
        return returnString;
    }



    private class DoubleNode {
        private DoubleNode _previous;
        private DoubleNode _next;
        private T _value;

        public DoubleNode() {
            _previous = null;
            _next = null;
            _value = null;
        }

        public DoubleNode(T value){
            _previous = null;
            _next = null;
            _value = value;
        }

    }

}

/**
 * DoubleOrderedList testing area.
 *
 * @author (your name), Acuna
 * @version (version)
 */
class Driver {
    public static void main(String [] args) {
        DoubleList<Integer> list = new DoubleList<>();

        //RA: These are _extremely_ simple tests - do not use them when doing
        //    your writeup.

        list.add(23);
        list.add(24);
        list.add(16);
        list.add(3);
        list.add(7);
        list.add(17);
        list.add(9);
        list.add(13);
        list.add(14);
        list.add(1);
        System.out.println("\nsize = " + list.size());

        System.out.println(list);

        list.remove(7);
        System.out.println(list);
        list.removeFirst();
        System.out.println(list);
        list.remove(17);
        System.out.println(list);
        list.removeLast();
        System.out.println(list);
        list.remove(14);
        System.out.println(list);
        list.removeLast();
        System.out.println(list);

I don't think your bug is in removeLast . It's in the remove function, and it corrupts your list, causing further manipulations of the list to behave incorrectly.

When you remove an item from the middle of a double linked list, you need to stitch up the item before the removed item, and the item after the removed item. You are doing the first operation, but not the second. For example, suppose I have three elements in the list: LX R. I want to remove X. I have to set L._next = R (you do that), and also set R._previous = L (you don't do that). At that point, your list becomes corrupt, because your reverse links are off.

Take a look at your loop at remove function.

do{
            if(current._value == element){
                temp = current._value;
                if(previous == null){
                    _head = _head._next;
                    _head._previous = null;
                }
                else{
                    previous._next = current._next;
                    //next line is missing
                    previous._next._previous = previous;
                }
            }
            previous = current;
            current = current._next;
        }while(current != null);

Also, it's not efficient to loop while(current != null), consider (while !found && current != null) or break statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM