我的任务是在java中实现循环链表(升序),但问题是它是在一个无限循环中
我创建了一个Node类,我在其中定义了两个元素。
public class Node {
public int element;
public Node next;
public class Node {
int element;
Node next;
}
}
现在在List的第二个类中,我已经创建了一个插入函数,我在开始时定义了一个Node head = null并创建了一个新的nNode。之后我在head头部分检查是否head == null然后是第一个元素将是nNode。插入第一个元素后,我将比较下一个元素和head元素,如果head元素大于它将接下来移动,新的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;
}
}
}
答案 0 :(得分:1)
我创建了圆形链表的示例程序,其中包含给定元素的名称和年龄。
它有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());
}
}
答案 1 :(得分:0)
让我们考虑以下情况:
该列表包含元素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
}
}
如您所见,您的代码中至少存在以下问题:
tNode.next=head;
不是必需的,因为如果您在pNode
和tNode
之间插入节点,tNode.next
不应受到影响(如果tNode
}是最后一个节点,next
应该已经指向头部,而在所有其他情况下,这个赋值将是错误的。)
在上面设置head
的两个分支中,您未将最后一个节点的next
元素设置为head
。如果你在添加第一个节点时没有这样做,那不一定是个问题,但在添加一个新的头(第二个条件)时将其排除在外你会产生一个错误的状态然后可能导致无休止的循环
您可能想要做什么:
删除tNode.next=head;
声明。
如果添加新头,则找到最后一个节点并将头设置为下一个节点。这意味着如果您只有一个节点,它会引用自身。如果在前面添加节点(第二个条件),则必须更新最后一个节点的next
引用,否则如果尝试添加元素,则会得到无限循环在末尾。
答案 2 :(得分:0)
在代码上工作了两天之后我终于解决了它,但这不是有效的代码。
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;
}
}