在java中实现一个链表

时间:2017-07-21 18:08:31

标签: java linked-list

我正在学习数据结构当前和下面是我对linkedlist的实现。我保持尽可能简单,因为我的目标是理解逻辑。

/*
 * Singly linked list
 */
package linkedlisttest;


class Node {
    int data;
    Node next;

    public Node(int data) 
    {
        this.data = data;
    }

}

class LinkedList {

    Node head;

    public void add(int data) 
    {
        if (head == null) 
        {
            head = new Node(data);  
            return;
        }

        Node current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = new Node(data);
    }

    public int getSize() {
        int i = 0;
        Node current = head;
        while (current != null) {
            i += 1;
            current = current.next;
        }
        return i;
    }

    public void add(int data, int index) 
    {
        if (head == null && index == 0) 
        {
              head = new Node(data);
              return;
        } else if (head == null && index != 0) {
              return; // invalid position
        } else if ( index > getSize() ) {
            return;
        }

        Node current = head;
        //iterate through whole list 
        int pos = -1; 
        Node previous = null;
        Node next = null;
        Node newNode = new Node(data);
        //find next and previous nodes with relation to position
        while (current != null) {
            if (pos == index - 1) {
                previous = current;
            } else if (pos == index + 1) {
                next = current;
            }
            pos++;
            current = current.next;
        }
        previous.next = newNode;

        newNode.next = next;

    }

    public void print() 
    {
        Node current = head;
        while (current.next != null) {
            System.out.print(current.data + "->");
            current = current.next;
        }
        System.out.print(current.data);
    }

}

public class LinkedListTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        LinkedList lt = new LinkedList();
        lt.add(3);
        lt.add(5);
        lt.add(6);
        lt.add(4,1);
        lt.print();
    }

}

lt.add(4,1)发生了这个错误,我怀疑是一个错误。

预期输出:3->4->6

实际输出:3->5->4

感谢帮助人员......

修改

感谢 @StephenP @rosemilk 的帮助。感谢上面的代码有一个逻辑错误,因为它取代了索引处的值,而不是添加它。

这是新的优化代码

/*
 * Singly linked list
 */
package linkedlisttest;

class Node {

    int data;
    Node next;

    public Node(int data) {
        this.data = data;
    }

}

class LinkedList {

    Node head;
    int size;

    /**
     *
     * @param data element to add to list 
     * Time Complexity : O(n)
     */
    public void add(int data) {
        if (head == null) {
            head = new Node(data);
            size += 1;
            return;
        }

        Node current = head;
        while (current.next != null) {
            current = current.next;
        }
        current.next = new Node(data);
        size += 1;
    }

    /**
     *
     * @return size of list 
     * Time Complexity: O(1) 
     * This is because we use a class
     * variable size to keep track of size of linked list
     */
    public int getSize() {
        return size;
    }
    /**
     * 
     * @param data element to insert 
     * @param index position at which to insert the element (zero based)
     * Time Complexity : O(n)
     */
    public void add(int data, int index) {

        if (index > getSize()) {
            return; // invalid position
        }

        Node current = head; //iterate through whole list 
        int pos = 0;
        Node newNode = new Node(data);

        if (index == 0) // special case, since its a single reference change!
        {
            newNode.next = head;
            head = newNode; // this node is now the head
            size += 1;
            return;
        }
        while (current.next != null) {
            if (pos == index - 1) {
                break;
            }
            pos++;
            current = current.next;
        }
        // These are 2 reference changes, as compared to adding at index 0
        newNode.next = current.next; // here we are changing a refernce
        current.next = newNode; // changing a reference here as well
        size += 1;

    }

    /**
     * Prints the whole linked list 
     * Time Complexity : O(n)
     */
    public void print() {

        if(getSize() == 0) { //list is empty
            return;
        }
        Node current = head;
        while (current.next != null) {
            System.out.print(current.data + "->");
            current = current.next;
        }
        System.out.print(current.data + "\n"); 
    }
}

public class LinkedListTest {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        LinkedList lt = new LinkedList();
        lt.print();
        lt.add(3);
        lt.add(5);
        lt.add(6);
        lt.print();
        lt.add(4, 1);
        lt.print();
        lt.add(4, 7);// 7 is an invalid index
        lt.add(8, 3);
        lt.print();
    }

}

2 个答案:

答案 0 :(得分:2)

您的add (int , int )函数存在逻辑错误,可以做得更好。您不需要先前的当前和下一个引用,并且可以仅使用对当前节点的引用巧妙地操作列表,分别处理索引0处的扩散。我会写add函数如下

public void add(int data, int index) 
{
    if ( index > getSize() ) {
        return; // invalid position
    }

    Node current = head; //iterate through whole list 
    int pos = 0; 
    Node newNode = new Node(data);

    if (index == 0) // special case, since its a single reference change!
    {
        newNode.next = head; 
        head = newNode; // this node is now the head
        return;
    }
    while (current.next != null) {
        if (pos == index - 1) {
            break;
        }
        pos++;
        current = current.next;
    }
    // These are 2 reference changes, as compared to adding at index 0
    newNode.next = current.next; // here we are changing a refernce
    current.next = newNode; // changing a reference here as well

}

此外,当您尝试打印空列表时,print函数会提供NullPointerException。我会写这样的打印功能,

public void print() 
{
    Node current = head;
    while (current != null) {
        System.out.print(current.data + "->");
        current = current.next;
    }
    System.out.println("null"); // this is just to say last node next points to null!
}

希望这会有所帮助:)

答案 1 :(得分:0)

目前,如果你在循环中打印出next,索引是-1,0,1(而不是0,1,2),所以它永远不会"找到&#34 34;正确的int pos = -1;。将int pos = 0;替换为3->4->5->6并使其正常工作。

我同意@StephenP,输出应该(可以说)是 function initalize_daterange() { console.log("It has been loaded!"); if( typeof ($.fn.daterangepicker) === 'undefined'){ return; } var cb = function(start, end, label) { console.log(start.toISOString(), end.toISOString(), label); $('#questionsrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY')); minimum = Date.parse(start.toISOString()).getTime(); maximum = Date.parse(end.toISOString()).getTime(); $(document).trigger("load_chart"); }; var optionSet1 = { startDate: moment().subtract(29, 'days'), endDate: moment(), minDate: '06/10/2017', maxDate: moment(), dateLimit: { days: 60 }, showDropdowns: true, showWeekNumbers: true, timePicker: false, timePickerIncrement: 1, timePicker12Hour: true, ranges: { 'Today': [moment(), moment()], 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], 'Last 7 Days': [moment().subtract(6, 'days'), moment()], 'Last 30 Days': [moment().subtract(29, 'days'), moment()], 'This Month': [moment().startOf('month'), moment().endOf('month')], 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')] }, opens: 'left', buttonClasses: ['btn btn-default'], applyClass: 'btn-small btn-primary', cancelClass: 'btn-small', format: 'MM/DD/YYYY', separator: ' to ', locale: { applyLabel: 'Submit', cancelLabel: 'Clear', fromLabel: 'From', toLabel: 'To', customRangeLabel: 'Custom', daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], firstDay: 1 } }; $('#questionsrange span').html(moment().subtract(29, 'days').format('MMMM D, YYYY') + ' - ' + moment().format('MMMM D, YYYY')); $('#questionsrange').daterangepicker(optionSet1, cb); $('#questionsrange').on('show.daterangepicker', function() { console.log("show event fired"); }); $('#questionsrange').on('hide.daterangepicker', function() { console.log("hide event fired"); }); $('#questionsrange').on('apply.daterangepicker', function(ev, picker) { console.log("apply event fired, start/end dates are " + picker.startDate.format('MMMM D, YYYY') + " to " + picker.endDate.format('MMMM D, YYYY')); }); $('#questionsrange').on('cancel.daterangepicker', function(ev, picker) { console.log("cancel event fired"); }); $('#options1').click(function() { $('#questionsrange').data('daterangepicker').setOptions(optionSet1, cb); }); $('#options2').click(function() { $('#questionsrange').data('daterangepicker').setOptions(optionSet2, cb); }); $('#destroy').click(function() { $('#questionsrange').data('daterangepicker').remove(); }); } ,但这是一个设计决定。