Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 按升序排列的循环链表_Java_Linked List - Fatal编程技术网

Java 按升序排列的循环链表

Java 按升序排列的循环链表,java,linked-list,Java,Linked List,我的任务是用java实现一个循环链表(升序),但问题是它是在一个无限循环中运行的 我创建了一个节点类,在其中定义了两个元素 public class Node { public int element; public Node next; public class Node { int element; Node next; } } 现在,在列表的第二个类中,我创建了一个插入函数,我在start中定义了一个节点head=null

我的任务是用java实现一个循环链表(升序),但问题是它是在一个无限循环中运行的

我创建了一个节点类,在其中定义了两个元素

public class Node {
    public int element;
    public Node next;

    public class Node {
        int element;
        Node next;
    }
}
现在,在列表的第二个类中,我创建了一个插入函数,我在start中定义了一个节点head=null,并创建了一个新的nNode。之后,我在head部分检查head=null,那么第一个元素将是nNode。插入第一个元素后,我将比较下一个元素和head元素,如果head元素大于它将移动next,新的nNode将是head。因为它是一个循环链表,所以它在工作,但它也在无限循环中运行

这是我使用节点类变量的List类

public class List {
    void insert(int e) {
        Node nNode = new Node();
        Node tNode = head;
        nNode.element = e;

        if (head == null)
            head = nNode;                      
        else if (head.element > e) {                        
            nNode.next = head;
            head=nNode;
        } else {
            Node pNode = head;

            while (tNode.next != head && tNode.element <= e) {
                pNode = tNode;
                tNode = tNode.next;
            }

            pNode.next = nNode;
            nNode.next = tNode;
            tNode.next=head;                                           
        }
    }
}
公共类列表{
空白插入(INTE){
Node nNode=新节点();
节点tNode=头部;
nNode.element=e;
if(head==null)
头=n节点;
如果(head.element>e){
nNode.next=头部;
头=n节点;
}否则{
节点pNode=头;

当(tNoDe.NeX.= Head & tNODE.Engult

)让我们考虑以下情况:

该列表包含元素B、C、X。现在要插入A,然后插入Z

void insert(int e) {
    Node nNode = new Node();  //the new node, step 1: A, step2: Z
    Node tNode = head; //step1: points to B, step2: points to A
    nNode.element = e; 

    if (head == null) { //false in both steps
        head = nNode;
        head.next = head; //I added this line, otherwise you'd never get a circular list 
    } //don't forget the curly braces when adding more than one statement to a block
    else if (head.element > e) {  //true in step 1, false in step 2                     
        nNode.next = head; //A.next = A
        head=nNode; //A is the new head, but X.next will still be B
    } else {
        //you'll enter here when adding Z
        Node pNode = head; //points to A because of step 1

        //when tNode = X you'll start over at B, due to error in step 1
        //the condition will never be false, since no node's next will point to A
        //and no node's element is greater than Z
        while (tNode.next != head && tNode.element <= e) {
            pNode = tNode;
            tNode = tNode.next;
        }

        //in contrast to my previous answer, where I had an error in my thought process,
        //this is correct: the node is inserted between pNode and tNode
        pNode.next = nNode;                        
        nNode.next = tNode; 

        tNode.next=head; //delete this
    }
}
void插入(int e){
Node nNode=new Node();//新节点,步骤1:A,步骤2:Z
节点tNode=head;//步骤1:指向B,步骤2:指向A
nNode.element=e;
如果(head==null){//false在两个步骤中
头=n节点;
head.next=head;//我添加了这一行,否则您永远不会得到循环列表
}//向块中添加多个语句时,不要忘记大括号
否则,如果(head.element>e){//true在步骤1中,false在步骤2中
nNode.next=head;//A.next=A
head=nNode;//A是新的头,但X.next仍然是B
}否则{
//添加Z时,您将在此处输入
节点pNode=head;//由于步骤1,指向
//当tNode=X时,由于步骤1中的错误,您将在B处重新开始
//条件永远不会为false,因为没有节点的下一个将指向
//并且没有节点的元素大于Z

虽然(tNode.next!=head&&tNode.element在代码上工作了两天后,我终于解决了它,但这不是有效的代码

 void insert(int e) {
        Node nNode = new Node();  //the new node, step 1: A, step2: Z
        Node tNode = head; //step1: points to B, step2: points to A
        nNode.element = e; 


        if (head == null) { //false in both steps
            head = nNode;
            head.next = head;
        }
        else if (head.element > e) {  //true in step 1, false in step 2
              Node pNode = head; 
            pNode=tNode.next;    //PNode is at head which will equal to tNode.next Which                  will be the next element
              nNode.next = head;
            head=nNode;
            tNode.next.next=nNode;   // Now I am moving the Tail Node next
        } else {

            Node pNode=head; //points to A because of step 1


            while (tNode.next != head && tNode.element <= e) {
                pNode = tNode;
                tNode = tNode.next;
            }


            pNode.next = nNode;                        
            nNode.next = tNode;

        }   
    }
void插入(int e){
Node nNode=new Node();//新节点,步骤1:A,步骤2:Z
节点tNode=head;//步骤1:指向B,步骤2:指向A
nNode.element=e;
如果(head==null){//false在两个步骤中
头=n节点;
head.next=head;
}
否则,如果(head.element>e){//true在步骤1中,false在步骤2中
节点pNode=头;
pNode=tNode.next;//pNode位于head,它将等于tNode.next,它将是下一个元素
nNode.next=头部;
头=n节点;
tNode.next.next=nNode;//现在我正在下一步移动尾部节点
}否则{
节点pNode=head;//由于步骤1,指向

while(tNode.next!=head&&tNode.element我在示例程序中为保存给定元素名称和年龄的循环linkedlist创建了一个。 它有
add()
remove()
sorbasedOnAge()
(排序是通过首先获取克隆并将其转换为简单的链表来实现的。然后使用合并排序,以实现O(nLogn)的性能。)

若你们喜欢,别忘了按“喜欢”按钮

package com.ash.practice.tricky;

import java.util.Collections;
import java.util.LinkedList;

public class CircularLinkedList implements Cloneable{

Node start;

public Node getHead() {
    return start;
}

CircularLinkedList setHead(Node startNode) {
    start = startNode;
    return this;
}

public void add(String name, int age) {

    if(name==null) {
        System.out.println("name must not be null.");
        return;
    }

    if(start == null) {
        Node node = new Node(name,age);
        start = node;
        node.next = start;
    } else {

        Node node = new Node(name,age);
        Node temp = start;
        while(temp.next != start) {
            temp = temp.next;
        }
        temp.next = node;
        node.next = start;
    }
}

public CircularLinkedList clone()throws CloneNotSupportedException{  
    return (CircularLinkedList)super.clone();  
}  

public boolean remove(String name) {
    if(name==null) {
        return false;
    } else if(start==null) {
        return false;
    } else if(start.getName().equals(name)) {
        if(size()>1) {
            Node temp = start;
            while(temp.next!=start) {
                temp = temp.next;
            }
            temp.next = start.next;
            start = start.next;
        } else {
            start = null;
        }
        return true;
    } else {
        Node temp = start;
        Node next = null;
        Node prev = null;

        while(temp.next != start) {
            String currName = temp.name;
            if(currName.equals(name)) {
                next = temp.next;
                break;
            } else {
                temp = temp.next;
            }
        }
        if(next == null) {
            return false;
        }
        prev = temp.next;
        while(prev.next!=temp) {
            prev = prev.next;
        }
        prev.next = next;
        temp = null;
        return true;
    }
}

/*  

public Node getPrevious(String name, int age) {
    Node curr = new Node(name,age);
    Node temp = curr;
    while(temp.next!=curr) {
        temp = temp.next;
    }
    return temp;
}

 */

public int size() {
    int count = 1;
    if(start != null) {
        Node temp = start;
        while(temp.next!=start) {
            count++;
            temp = temp.next;
        }
    } else return 0;
    return count;
}

public int listSize() {
    int count = 1;
    if(start != null) {
        Node temp = start;
        while(temp.next!=null) {
            count++;
            temp = temp.next;
        }
    } else return 0;
    return count;
}

public void display() {
    if(start == null) {
        System.out.println("No element present in list.");
    } else {
        Node temp = start;
        while(temp.next != start) {
            System.out.println(temp);
            temp = temp.next;
        }
        System.out.println(temp);
    }
}

public void displayList() {
    if(start == null) {
        System.out.println("No element present in list.");
    } else {
        Node temp = start;
        while(temp.next != null) {
            System.out.println(temp);
            temp = temp.next;
        }
        System.out.println(temp);
    }
}

public Node getPrevious(Node curr) {
    if(curr==null) {
        return null;
    } else {
        Node temp = curr;
        while(temp.next!=curr) {
            temp = temp.next;
        }
        return temp;
    }
}

Node getMiddle() {
    Node result = null;
    Node temp = start.next;
    result = start.next;
    Node end = getPrevious(start);
    end.next = null;

    while(temp.next!=null) {
        if(temp.next.next!=null) {
            temp = temp.next.next;
            result = result.next;
        } else {
            return result;
        }
    }
    return result;
}

private static CircularLinkedList SortCollections(CircularLinkedList list) {
    return SortCollections.doSortBasedOnAge(list);
}

private static class Node {
    Node next;
    String name;
    int age;

    Node(String name,int age) {
        this.name = name;
        this.age = age;
    }

    String getName() {
        return name;
    }

    int getAge() {
        return age;
    }

    public String toString() {
        return "name = "+name +" : age = "+age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Node other = (Node) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

private static class SortCollections {

    static Node mergeSort(Node head) {
        if(head == null || head.next == null) {
            return head;
        }

        Node middle = getMiddle(head);
        Node nextHead = middle.next;
        middle.next = null;

        Node left = mergeSort(head);
        Node right =  mergeSort(nextHead);
        Node sortedList = sortedMerged(left, right);
        return sortedList;
    }

    public static  CircularLinkedList doSortBasedOnAge(CircularLinkedList list) {
        CircularLinkedList copy = null;
        try {
            copy = list.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        if(copy!=null) {
            Node head = copy.getHead();
                            Node end = copy.getPrevious(head);
            end.next = null;
            Node startNode = mergeSort(head);

            CircularLinkedList resultList = new CircularLinkedList().setHead(startNode);
            return resultList;
        } else {
            System.out.println("copy is null");
        }
        return null;
    }

    private static Node sortedMerged(Node a, Node b) {
        if(a == null) {
            return b;
        } else if(b == null) {
            return a;
        }

        Node result = null;
        if(a.getAge() > b.getAge()) {
            result = b;
            result.next = sortedMerged(a, b.next);
        } else {
            result = a;
            result.next = sortedMerged(a.next, b);
        }

        return result;
    }

    private static Node getMiddle(Node head) {
        Node result = null;
        Node temp = head;
        result = head;

        while(temp.next!=null) {
            if(temp.next.next!=null) {
                temp = temp.next.next;
                result = result.next;
            } else {
                return result;
            }
        }
        return result;
    }

}
public static void main(String[] args) {

    CircularLinkedList list = new CircularLinkedList();
    Collections.sort(new LinkedList());
    list.add("ashish", 90);
    list.add("rahul", 80);
    list.add("deepak", 57);
    list.add("ankit", 24);
    list.add("raju", 45);
    list.add("piyush", 78);
    list.add("amit", 12);
    //list.display();
    /*System.out.println("---------------- size = "+list.size());
    System.out.println(list.remove("deepak"));
    //list.display();
    System.out.println("---------------- size = "+list.size());
    System.out.println(list.remove("ashish"));
    //list.display();
    System.out.println("---------------- size = "+list.size());
    System.out.println(list.remove("raju"));
    //list.display();
    System.out.println("---------------- size = "+list.size());
    list.add("aman", 23);
    System.out.println("---------------- size = "+list.size());
    list.display();
    System.out.println("Previous Node of second node is : "+list.getPrevious(list.start.next));
    System.out.println("Previous Node of start node is : "+list.getPrevious(list.start));
    System.out.println("Previous Node of piyush node is : "+list.getPrevious("piyush",78));*/
    list.display();
    System.out.println("---------------- size = "+list.size());
    //System.out.println(list.getMiddle());
    CircularLinkedList newList = CircularLinkedList.SortCollections(list);
    newList.displayList();
    System.out.println("---------------- size = "+newList.listSize());
}

}

我想你的意思是你的
while
-循环没有终止。你调试过吗?在什么情况下会发生?tNode.next=head;这种情况下,但此代码是循环列表中最重要的部分。@Thomasit将最后一个节点指向第一个节点,这就是我们在循环链接列表中所做的。最后一个节点具有引用如果我没有错过什么东西<代码> tNo.Next=Head;< /Calp>可能确实是问题。考虑在中间插入一个元素,<代码> tNoD[/COD> >将不是最后一个节点,因此不会有<代码>头<代码>作为下一个节点。嗯,是什么解决方案呢?m对我来说,通过算法很容易理解真的很困惑…!!@mathlearner什么让人困惑?试着实现下面的前两段“你可能想做什么:”。它基本上只是一个附加的分配给
next
,用于结束循环和循环后的if-else分支。它将转到我的头上..!!谢谢你的帮助。在我的程序中,pNode是前一个节点,tNode是当前节点,我不明白你想说什么。好吧,你可以在节点上迭代直到你得到最后一个或只是在你的列表中存储一个引用,就像
head
一样。然后每当你添加一个新的尾部时,你就必须更新引用,但这应该不是一个大问题。你添加的代码也是错误的,因为
tNode
被初始化为head,因此
tNode.next.next=nNode;
将设置
next
将第二个节点引用到新节点-谁应该是新的头。这可以用于添加67、31、1、2,但如果在1之前添加2,则会失败,即67、31、2、1。是的@Thomas,但它如何正确工作可以生成比此更好的代码?我已经描述了您可以做的事情:存储对最后一个节点的引用并需要时更新它。我通常很犹豫是否提供代码,因为这是您的练习,所以您应该是编写代码的人。只要确保您测试不同的使用模式(更多元素、重复元素、不同顺序等),并在代码无法按预期工作时仔细调试代码。