【问题标题】:Splitting a Circular Linked List in to two halves将循环链表分成两半
【发布时间】:2015-01-14 00:57:44
【问题描述】:

我正在处理一个问题,我要将循环链表分成两半。如果列表是偶数,则拆分将导致两个偶数列表。如果拆分是奇数,则第一个列表将具有额外的节点。

以下是我的节点类的代码

public class CLLNode {

    private int data;
    private CLLNode next;

    public CLLNode(int d)
    {
        this.data = d;
    }

    public void setData(int d)
    {
        this.data = d;
    }

    public int getData()
    {
        return this.data;
    }

    public void setNext(CLLNode n)
    {
        this.next = n;
    }

    public CLLNode getNext()
    {
        return this.next;
    }

}

以下是我的循环链表类的代码

public class CLinkedList {

    private CLLNode Head;

    public CLinkedList()
    {
        Head = null;
    }

    public CLLNode getHead()
    {
        return this.Head;   
    }

    public void insertFirst(int d)
    {
        CLLNode n = new CLLNode(d);
        if(Head == null)
        {
            this.Head = n;
            n.setNext(n);
        }
        else
        {
            CLLNode temp = this.Head;
            while(temp.getNext()!= this.Head)
            {
                temp = temp.getNext();
            }
            n.setNext(this.Head);
            temp.setNext(n);
            this.Head = n;
        }
    }

    public void insertLast(int d)
    {
        CLLNode n = new CLLNode(d);
        if(Head == null)
        {
            this.Head = n;
            n.setNext(n);
        }
        else
        {
            CLLNode temp = this.Head;
            while(temp!= null)
            {
                temp = temp.getNext();
                if(temp.getNext() == this.Head)
                {
                    break;
                }
            }

            n.setNext(temp.getNext());
            temp.setNext(n);
        }

    }

    public void deleteFirst()
    {
        CLLNode temp = this.Head;
        CLLNode temp2 = this.Head;

        while(temp2!=null)
        {
            temp2 = temp2.getNext();
            if(temp2.getNext()== this.Head)
            {
                break;
            }
        }

        temp2.setNext(temp.getNext());
        this.Head = temp.getNext();
        temp.setNext(null);
    }

    public void deleteLast()
    {
        CLLNode temp = this.Head;
        CLLNode temp2 = this.Head;

        while(temp.getNext()!= this.Head)
        {
            temp2 = temp;
            temp = temp.getNext();
        }

        temp2.setNext(temp.getNext());
        temp = null;
    }

    public void displayList(CLLNode n)
    {
        CLLNode temp = n;
        while(temp!= null)
        {
            System.out.println(temp.getData());
            temp = temp.getNext();
            if(temp == this.Head)
            {
                break;
            }
        }
    }

    public int getLength()
    {
        int count  = 0;
        CLLNode temp = this.Head;
        while(temp != null)
        {
            count ++;
            temp = temp.getNext();
            if(temp == this.Head){
                break;
                }
        }

        return count;
    }

    public void splitList(CLLNode head, CLLNode head1, CLLNode head2)
    {
        CLLNode temp1 = head;
        CLLNode temp2 = head;
        CLLNode temp3 = head;

        while(temp2!=null)
        {
            temp1 = temp1.getNext();
            temp2 = temp2.getNext().getNext();

            if(temp2.getNext()== head)
            {
                temp2.setNext(temp1.getNext());
                head2 = temp1.getNext();
                temp1.setNext(temp3);
                head1 = temp3;
                break;
            }

            if(temp2.getNext().getNext()==head)
            {
                temp2.getNext().setNext(temp1.getNext());
                head2 = temp2;
                temp1.setNext(temp3);
                head1 = temp3;
                break;
            }
        }
        this.displayList(Head1); // This one goes in to a infinite loop..
        this.displayList(head2);

    }

}

以下是我的主要课程

public class main {

    public static void main(String[] args) {



        CLinkedList list = new CLinkedList();

        list.insertLast(10);
        list.insertLast(20);
        list.insertLast(30);
        list.insertLast(40);

        CLLNode head = list.getHead();

        CLLNode head1 = null;
        CLLNode head2 = null;

        list.splitList(head,head1,head2);



    }

}

我能够成功拆分我相信的列表,但由于某种原因,当我显示新拆分的列表时,它会进入无限循环。我不知道为什么,如果有人能指出我的错误或提出修复建议,我将不胜感激。

【问题讨论】:

  • temp2 = temp2.getNext().getNext(); - 尝试使用单个节点的列表。通常,您应该首先使用一个空列表进行测试,然后是一个节点,然后是两个,以此类推,以消除任何皱纹。

标签: algorithm linked-list circular-list


【解决方案1】:

我不知道您的拆分操作是如何工作的,但是有一种非常简单的方法可以将一个循环列表拆分为两个循环列表。现在让我们不要担心偶数/奇数的东西,并考虑如果交换循环列表中两个不同节点的下一个指针会发生什么。你会得到两个循环列表(很整洁,对吗?)。

现在要拆分列表,首先计算列表中的项目数(称为n)并将位置0(第一个节点)的节点的next指针与位置n/2的节点的next指针交换(您必须按照下一个指针找到该节点)。如果计数为偶数,则将列表拆分为两个偶数长度的列表,如果计数为奇数,则将这些列表分别拆分为两个奇数/偶数长度的列表。所以找到这两个节点,交换它们的next指针并将它们分配给head1和head2。

您可能希望单独处理存在单个节点或列表为空的情况。

在一张纸上试一试,看看它确实有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 2013-05-25
    • 2013-12-06
    相关资源
    最近更新 更多