How to sort a Linked list - java

I created a linked list using nodes that prints out a list(string) of names. I'm trying to write a sort method that prints out the names in alphabetical order. If this was integers it would be easy but I have no idea how to go about doing this. Any help or tips are appreciated.
-I cannot use the builtin collections.sort(). I need to make my own method.
SortMethod: (this is what I used when I was printing a list of numbers out but now its strings so I know I can't use the > operator. I just don't know how to replace it.
public void Sort( BigNode front)
{
BigNode first,second,temp;
first= front;
while(first!=null) {
second = first.next;
while(second!=null) {
if(first.dataitems < second.dataitems)
{
temp = new BigNode();
temp.dataitems =first.dataitems;
first.dataitems = second.dataitems;
second.dataitems = temp.dataitems;
}
second=second.next;
}
Heres the rest of program(I dont think its needed but just in case)
import java.util.*;
public class BigNode {
public String dataitems;
public BigNode next;
BigNode front ;
BigNode current;
String a = "1", b = "2", c = "3", d = "4";
String[] listlength;
public void initList(){
front = null;
}
public BigNode makeNode(String number){
BigNode newNode;
newNode = new BigNode();
newNode.dataitems = number;
newNode.next = null;
return newNode;
}
public boolean isListEmpty(BigNode front){
boolean balance;
if (front == null){
balance = true;
}
else {
balance = false;
}
return balance;
}
public BigNode findTail(BigNode front) {
BigNode current;
current = front;
while(current.next != null){
//System.out.print(current.dataitems);
current = current.next;
} //System.out.println(current.dataitems);
return current;
}
public void addNode(BigNode front ,String name){
BigNode tail;
if(isListEmpty(front)){
this.front = makeNode(name);
}
else {
tail = findTail(front);
tail.next = makeNode(name);
}
}
public void addAfter(BigNode n, String dataItem2) { // n might need to be front
BigNode temp, newNode;
temp = n.next;
newNode = makeNode(dataItem2);
n.next = newNode;
newNode.next = temp;
}
public void findNode(BigNode front, String value) {
boolean found , searching;
BigNode curr;
curr = front;
found = false;
searching = true;
while ((!found) && (searching)) {
if (curr == null) {
searching = false;
}
else if (curr.dataitems == value) { // Not sure if dataitems should be there (.data in notes)
found = true;
}
else {
curr = curr.next;
}
}
System.out.println(curr.dataitems);
}
public void deleteNode(BigNode front, String value) {
BigNode curr, previous = null; boolean found;
if (!isListEmpty(front)){
curr = front;
found = false;
while ((curr.next != null) && (!found)) {
if(curr.dataitems.equals(value)) {
found = true;
}
else {
previous = curr;
curr = curr.next;
}
}
if (!found) {
if(curr.dataitems.equals(value)) {
found = true;
}
}
if (found) {
if (curr.dataitems.equals(front.dataitems)){ // front.dataitems may be wrong .dataitems
front = curr.next;
} else {
previous.next = curr.next;
}
} else {
System.out.println("Node not found!");
//curr.next = null; // Not sure If this is needed
}
}
showList(front);
}
public void printNodes(String[] len){
listlength = len;
int j;
for (j = 0; j < len.length; j++){
addNode(front, len[j]);
} showList(front);
}
public void showList(BigNode front){
current = front;
while ( current.next != null){
System.out.print(current.dataitems + ", ");
current = current.next;
}
System.out.println(current.dataitems);
MenuOptions();
}
public void MenuOptions() {
Scanner in = new Scanner(System.in);
System.out.println("Choose an Option Below:");
System.out.println(a + "(Display Length of List)" + ", " + b + "(Delete a person)" + ", " + c + ("(Exit)"));
String pick = in.nextLine();
if (pick.equals(b)) {
System.out.println("Who would you like to delete?");
String delete = in.nextLine();
deleteNode(front, delete);
}
if (pick.equals(a)) {
System.out.println("Length of List = " + listlength.length);
MenuOptions();
}
if (pick.equals(c)) {
}
}
public static void main(String[] args) {
String[] names = {"Billy Joe", "Sally Mae", "Joe Blow", "Tasha Blue", "Malcom Floyd"}; // Trying to print theses names..Possibly in alphabetical order
BigNode x = new BigNode();
x.printNodes(names);
}
}

first.dataitems.compareTo(second.dataitems)<0
or if you have a comparator
comp.compare(first.dataitems, second.dataitems)<0

Related

How can I add an item to the end the a Linked List?

I am working on a project for my Data Structures class that asks me to write a class to implement a linked list of ints.
Use an inner class for the Node.
Include the methods below.
Write a tester to enable you to test all of the methods with whatever data you want in any order.
I have to create a method called "public void addToBack(int item)". This method is meant to "Add an Item to the end of the list" I have my code for this method down below. When I execute this method my list becomes empty. Does someone know what I did wrong and how to fix it?
import java.util.Random;
import java.util.Scanner;
public class LinkedListOfInts {
Node head;
Node tail;
private class Node {
int value;
Node nextNode;
public Node(int value, Node nextNode) {
this.value = value;
this.nextNode = nextNode;
}
}
public LinkedListOfInts(LinkedListOfInts other) {
Node tail = null;
for (Node n = other.head; n != null; n = n.nextNode) {
if (tail == null)
this.head = tail = new Node(n.value, null);
else {
tail.nextNode = new Node(n.value, null);
tail = tail.nextNode;
}
}
}
public LinkedListOfInts(int[] other) {
Node[] nodes = new Node[other.length];
for (int index = 0; index < other.length; index++) {
nodes[index] = new Node(other[index], null);
if (index > 0) {
nodes[index - 1].nextNode = nodes[index];
}
}
head = nodes[0];
}
public LinkedListOfInts(int N, int low, int high) {
Random random = new Random();
for (int i = 0; i < N; i++)
this.addToFront(random.nextInt(high - low) + low);
}
public void addToFront(int x) {
head = new Node(x, head);
}
public void addToBack(int x) {
if (head == null) {
head = new Node(x, head);
return;
}
tail = head;
while (tail.nextNode != null) {
tail = tail.nextNode;
}
tail.nextNode = new Node(x, tail);
}
public String toString() {
String result = "";
for (Node ptr = head; ptr != null; ptr = ptr.nextNode) {
if (!result.isEmpty()) {
result += ", ";
}
result += ptr.value;
}
return "[" + result + "]";
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
LinkedListOfInts list = new LinkedListOfInts(10, 1, 20);
boolean done = false;
while (!done) {
System.out.println("1. Add to Back");
System.out.println("2. toString");
switch (input.nextInt()) {
case 1:
System.out.println("Add an Item to the Back of a List.");
list.addToBack(input.nextInt());
break;
case 2:
System.out.println("toString");
System.out.println(list.toString());
break;
}
}
}
}
When you add to the tail the nextNode should point to null
tail.nextNode = new Node(x, null);
At the moment you are having an endless loop

Deleting a specific node in a singly linked list(java)

So my problem is that I wanna delete a node based on a value inputted by the user, in my program I can already, add, search, and delete the node in the last position, but so far I haven't been able to delete a specific value inputted by the user, if for example I have 1,2,3,4 elements in my list I wanna be able to point at, say 2, and delete it. here are my functions, the last one is the uncompleted one:
//searches node
public void searchNode(int input){
Node temp = first;
boolean found = false;
if(!isEmpty()){
for(int i = 0 ; i<size ; i ++){
if(temp.value == input){
System.out.println(input + " found in the position: " + (i+1));
found = true;
break;
}
temp = temp.rightNode;
}
if(!found)
System.out.println("value not found.");
}
}
//deletes last node
public void deleteLastNode(){
if(isEmpty()){
System.out.println("There are no nodes to delete.");
}
if(last == first){
first = null;
last = null;
} else {
Node current = first;
while(current.rightNode != last){
current = current.rightNode;
}
current.rightNode = null;
last = current;
}
size --;
}
//delete element, input by user.
public void deleteInputByUser(int input) {
Node temp = first;
boolean found = false;
if(isEmpty()){
System.out.println("There are no nodes to delete.");
} else {
}
size--;
}
//Node class
public class Node{
int value;
Node rigthNode;
public Node(int value){
this.value = value;
}
}
Deletion of a node in a Linked List by value is not so bad. This pseudocode should help you get started:
deleteNodeByValue(int val) {
if (head.val = val) {
head = head.next
return
}
current = head
while (current.next != null) {
if (current.next.val = val) {
current.next = current.next.next
return
}
current = current.next
}
}
Find the nodeToDelete and his previousNode, then
previousNode.rightNode = nodeToDelete.rightNode;
you can do it this way. The following code will remove the element once the index is given.
public boolean deleteAt(int index){
Node current=first;
if(index==0){
first=current.rightNode;
return true;
}
currentIndex=0;
previousNode=first;
current=first.rightNode;
while(current!=null){
if(currentIndex==index){
previousNode.rightNode=current.rightNode;
return true;
}
currentIndex++;
previousNode=current;
current=current.rightNode;
}
return false;
}
You could try something like that.
public void deleteNodeByValue(int input) {
Node currNode = first;
boolean found = false;
Node prevNode = first;
if (!isEmpty()) {
for (int i = 0; i < size; i++) {
if (currNode.value == input) {
///////DELETE START
if (currNode == first) {
first = currNode.rightNode;
} else {
prevNode.rightNode = currNode.rightNode;
if (currNode == last)
last = prevNode;
}
////DELETE END
found = true;
size--;
break;
}
prevNode = currNode;
currNode = currNode.rightNode;
}
if (!found)
System.out.println("value not found.");
}
}

I need help making a toString method that must pass certain tests, Java

I need help making this toString method pass the tests at the bottom. I am currently getting the error (expected:<0:20, 1:[1]0> but was <0:20, 1:[2]0>). addFirst is working 100%, but I'm not sure what is wrong here.
public class LList
{
public Node head;
private int i;
private int size;
public void addFirst(int value)
{
Node n = new Node();
n.value = value;
n.next = head;
head = n;
}
public void removeFirst()
{
if (head != null)
{
// commone case: there is at least one node
head = head.next;
}
else
{
// no nodes
throw new Banana();
}
}
public int size()
{
Node current = head;
int count = 0;
while(current != null)
{
count++; // keep count of nodes
current = current.next; // move to next node
}
return count;
}
public int get(int index)
{
int count = 0;
Node current = head;
if (index < 0 || index >= size())
{
throw new Banana();
}
while(count != index)
{
count++;
current = current.next;
}
return current.value;
}
public String toString()
{
String s = "";
Node current = head;
//current = head;
if (size() == 0)
{
return s;
}
else
{
s = s + "" + i + ":" + current.value;
for (int i = 1; i < size(); i++)
{
s = s + ", " + i + ":" + current.value;
}
return s;
}
}
public class Node
{
public int value;
public Node next;
}
#Test
public void testToString()
{
LList a = new LList();
assertEquals("", a.toString());
a.addFirst(10);
assertEquals("0:10", a.toString());
a.addFirst(20);
assertEquals("0:20, 1:10", a.toString());
a.addFirst(30);
assertEquals("0:30, 1:20, 2:10", a.toString());
}
You should iterate (walk over) all Nodes.
Use while loop for that, e.g.:
public String toString() {
String s = "";
Node current = head;
// current = head;
if (size() != 0) {
int i = 0;
s = s + "" + i + ":" + current.value;
while(current.next != null) {
i++;
current = current.next;
s = s + ", " + i + ":" + current.value;
}
}
return s;
}

Circular Linked List In Ascending Order Java

My task is to implement a circular linked list in java (ascending order) but the problem is that it is going in an infinite loop
I have created a class of Node in which i have define two elements.
public class Node {
public int element;
public Node next;
public class Node {
int element;
Node next;
}
}
Now in the second class of List i have made a insert function i have define a Node head=null in the start and create a new nNode .After that i am checking in the head section if head==null then the first element will be nNode. After inserting the first element i will compare the next element and the head element if the head element is greater than it will shift next and the new nNode will be the head. Since it is the circular linked list it is working but it is also going in an infinite loop.
This is the List class in which i have use the node class variables
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;
}
}
}
I have created on sample program for circular linkedlist which hold name and age of given element.
It has add(), remove() and sorbasedOnAge() (Sorting is implemented by first getting clone and convert it into simple linked list. Then use merge sort so that performance of O(nLogn) could be achieved.)
If you like it don't forget to press like button.
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());
}
}
Let's consider the following situation:
The list contains elements B,C,X. Now you want to insert A and then 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
}
}
As you can see, there are at least the following problems in your code:
tNode.next=head; is not necessary, since if you insert a node between pNode and tNode, tNode.next should not be affected (and if tNode is the last node, next should already point to the head, while in all other cases this assignment would be wrong).
In the two branches above, where you set head, you're not setting the next element of the last node to head. If you don't do this when adding the first node, that's not necessarily a problem, but leaving that out when adding a new head (second condition) you'll produce an incorrect state which then might result in endless loops
What you might want to do:
Remove the tNode.next=head; statement.
If you add a new head locate the last node and set the head as its next node. That means that if you have only one node, it references itself. If you add a node at the front (your second condition) you'll have to update the next reference of the last node, otherwise you'll get an endless loop if you try to add an element at the end.
After working two days on the code I finally solved it but this is not efficient code .
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;
}
}

How to display a string in linked list using nodes

I created a basic node linked list that displays the size of the list in number (ie: 0 - 9 )
Now I'm trying to alter what i have to display a list of names. I'm confused on what I need to change and what is going to be different. The names are going to be in string format. Eventually I'm going to read in a list of names from a txt file. For now I'm using just 3 names and test data.
import java.util.*;
public class Node {
public int dataitems;
public Node next;
Node front;
public void initList(){
front = null;
}
public Node makeNode(int number){
Node newNode;
newNode = new Node();
newNode.dataitems = number;
newNode.next = null;
return newNode;
}
public boolean isListEmpty(Node front){
boolean balance;
if (front == null){
balance = true;
}
else {
balance = false;
}
return balance;
}
public Node findTail(Node front) {
Node current;
current = front;
while(current.next != null){
//System.out.print(current.dataitems);
current = current.next;
} //System.out.println(current.dataitems);
return current;
}
public void addNode(Node front ,int number){
Node tail;
if(isListEmpty(front)){
this.front = makeNode(number);
}
else {
tail = findTail(front);
tail.next = makeNode(number);
}
}
public void printNodes(int len){
int j;
for (j = 0; j < len; j++){
addNode(front, j);
} showList(front);
}
public void showList(Node front){
Node current;
current = front;
while ( current.next != null){
System.out.print(current.dataitems + " ");
current = current.next;
}
System.out.println(current.dataitems);
}
public static void main(String[] args) {
String[] names = {"Billy Joe", "Sally Hill", "Mike Tolly"}; // Trying to print theses names..Possibly in alphabetical order
Node x = new Node();
Scanner in = new Scanner(System.in);
System.out.println("What size list? Enter Number: ");
int number = in.nextInt();
x.printNodes(number);
}
}
several things must be changed in my opinion
public void printNodes(String[] nameList){
int j;
for (j = 0; j < nameList.length; j++){
addNode(front, nameList[j]);
} showList(front);
}
you have to pass the array containing the names
x.printNodes(names);
also change:
public void addNode(Node front ,String name){
Node tail;
if(isListEmpty(front)){
this.front = makeNode(name);
}
else {
tail = findTail(front);
tail.next = makeNode(name);
}
}
and :
public Node makeNode(String name){
Node newNode;
newNode = new Node();
newNode.dataitems = name;
newNode.next = null;
return newNode;
}
and don't forget to change the type of dateitem into string :
import java.util.*;
public class Node {
public String dataitems;

Categories