The full code is a 2-3 tree implementation that requires me to be able to search for a book by any key(ISSN, Author[0], Author[1], Author[0] + "," + Author[1], or Title) The tree works by creating 5 copies of each book, each designated with one of the keys previously mentioned, and inserting them into their respective leaves. If a new book being inserted matches a key that has already been inserted into the tree (ie., James Henry, and James Joyce both would have a copy of their books inserted into the tree with key "james"), then instead of that new book being added into a leaf node at the bottom of the tree, it is added into a linked list inside of the node that already contains a copy all books with key == "james".
Class Tree23:
package tree23;
import bookClasses.*;
/**
* #author Chris
* #usage This Class builds a 2-3 tree that sorts Book entries based on ISSN value
*/
public class Tree23 {
public Node23 Root;
// PUBLIC FUNCTIONS //
public Tree23(){
Root = new Node23(true);
}
public void Insert(int issn, String title, String author){
String issnKey = null;
String titleKey = null;
String authorKey = null;
String author0Key = null;
String author1Key = null;
issnKey = String.valueOf(issn);
titleKey = title.toLowerCase();
authorKey = author.toLowerCase();
if(author.split(",").length == 2){
author0Key = author.split(",")[0].toLowerCase();
author1Key = author.split(",")[1].toLowerCase();
}
Book[] newBooks = new Book[5];
for(int i = 0; i < 5; i++){
newBooks[i] = new Book(issn, title, author);
}
InsertByKey(newBooks[0], issnKey);
InsertByKey(newBooks[1], titleKey);
InsertByKey(newBooks[2], authorKey);
if(author.split(",").length == 2){
InsertByKey(newBooks[3], author0Key);
InsertByKey(newBooks[4], author1Key);
}
}
public BookList GetBooksByAttribute(char attribute, String key){
BookList matches = null;
switch(attribute){
case 'i':
matches = GetBooksByISSN(Integer.valueOf(key));
break;
case 'n':
matches = GetBooksByAuthor(key.toLowerCase());
break;
case 't':
matches = GetBooksByTitle(key.toLowerCase());
break;
default:
break;
}
return matches;
}
// PRIVATE FUNCTIONS //
/*Insert Functions*/
private void InsertByKey(Book newBook, String key){
if(key.compareTo("james") == 0){
if(newBook.Title.toLowerCase().compareTo("finnegans wake") == 0){
System.out.print("");
}
}
//check for a node with matching key
Node23 targetNode = GetNodeByKey(Root, key);
//else find leaf for insert
if(targetNode == null){
targetNode = GetLeafByKey(Root, key);
}
//insert into target node
targetNode.AddBook(newBook, key);
if(key.compareTo("james") == 0){
System.out.print("");
}
if(targetNode.GetSize() == 3){
BalanceNodeOverflow(targetNode);
}
}
/*Search Functions*/
private BookList GetBooksByKey(Node23 n, String key){
BookList bList = null;
int match = n.GetMatchingBookListByKey(key);
if(match != -1){
bList = n.Books[match];
}
else{
int nextChild = DetermineNextTraversal(n, key);
bList = GetBooksByKey(n.Children[nextChild], key);
}
return bList;
}
private Node23 GetSuccessorLeaf(Node23 n, int index){
Node23 leaf = n.Children[index + 1];
while(!leaf.IsLeaf()){
leaf = leaf.Children[0];
}
return leaf;
}
private BookList GetBooksByISSN(int issn){
BookList keyMatches = GetBooksByKey(Root, String.valueOf(issn));
BookList issnMatches = null;
if(keyMatches != null){
issnMatches = keyMatches.GetBooksByISSN(issn);
}
return issnMatches;
}
private BookList GetBooksByAuthor(String author){
BookList keyMatches = GetBooksByKey(Root, String.valueOf(author));
BookList authorMatches = null;
if(keyMatches != null){
authorMatches = keyMatches.GetBooksByAuthor(author);
}
return authorMatches;
}
private BookList GetBooksByTitle(String title){
BookList keyMatches = GetBooksByKey(Root, String.valueOf(title));
BookList titleMatches = null;
if(keyMatches != null){
titleMatches = keyMatches.GetBooksByTitle(title);
}
return titleMatches;
}
private Node23 GetLeafByKey(Node23 n, String key){
//assumes that there is no node matching key, traverses from root to leaf node by key
//return key
Node23 leaf = n;
if(!n.IsLeaf()){
int nextChild = n.GetNextChildByKey(key);
leaf = GetLeafByKey(n.Children[nextChild], key);
}
return leaf;
}
private Node23 GetNodeByKey(Node23 n, String key){
Node23 match = null;
int nextChild;
int matchingBookList = n.GetMatchingBookListByKey(key);
if(matchingBookList >= 0){
match = n;
}
else{
nextChild = n.GetNextChildByKey(key);
if(nextChild != -1){
match = GetNodeByKey(n.Children[nextChild], key);
}
}
return match;
}
private int DetermineNextTraversal(Node23 n, String key){
int nextChild;
if(n.IsLeaf()){
nextChild = -1;
}
else if(n.GetSize() == 0){
nextChild = -1;
}
else if(n.GetSize() == 1){
if(n.Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else{
nextChild = 1;
}
}
else{
if(n.Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else if(n.Books[1].CompareTo(key) > 0){
nextChild = 1;
}
else{
nextChild = 2;
}
}
return nextChild;
}
/*Delete Functions*/
private void DeleteBookFromTree(Book b){
Node23 match;
int originalSize;
/*findNodeMatchingISSN*/
match = GetNodeByKey(Root, String.valueOf(b.ISSN));
originalSize = match.GetSize();
match.RemoveMatchingBook(b, String.valueOf(b.ISSN));
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
/*author[0]*/
match = GetNodeByKey(Root, b.Author[0]);
originalSize = match.GetSize();
match.RemoveMatchingBook(b, b.Author[0]);
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
if(b.Author.length == 2){
/*author[1]*/
match = GetNodeByKey(Root, b.Author[1]);
originalSize = match.GetSize();
match.RemoveMatchingBook(b, b.Author[1]);
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
/*author[0],author[1]*/
match = GetNodeByKey(Root, new String(b.Author[1] + "," + b.Author[2]));
originalSize = match.GetSize();
match.RemoveMatchingBook(b, new String(b.Author[1] + "," + b.Author[2]));
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
}
/*title*/
match = GetNodeByKey(Root, b.Title);
originalSize = match.GetSize();
match.RemoveMatchingBook(b, b.Author[1]);
if(originalSize > match.GetSize()){
BalanceNodeUnderflow(match);
}
}
/*Tree Balancing Functions*/
private void BalanceNodeOverflow(Node23 fullNode){
Node23[] splitNodes;
if(fullNode == Root){
Node23 newRoot = new Node23(false);
fullNode.Parent = newRoot;
splitNodes = fullNode.SplitNode();
fullNode.Parent.AddBookList(fullNode.RemoveBookList(0));;
newRoot.AddSplitNodeChildAt(0, splitNodes);
Root = newRoot;
}
else{
int position = fullNode.WhichChildAmI();
splitNodes = fullNode.SplitNode();
fullNode.Parent.AddBookList(fullNode.RemoveBookList(0));
fullNode.Parent.AddSplitNodeChildAt(position, splitNodes);
if(fullNode.Parent.GetSize() == 3){
BalanceNodeOverflow(fullNode.Parent);
}
}
}
private void RotateLeft1To0(Node23 parent){
Node23[] children = parent.Children;
children[0].AddBookList(parent.RemoveBookList(0));
parent.AddBookList(children[1].RemoveBookList(0));
children[1].ShiftBooksLeftInto(0);
}
private void RotateLeft2To1(Node23 parent){
Node23[] children = parent.Children;
children[1].AddBookList(parent.RemoveBookList(1));
parent.AddBookList(children[2].RemoveBookList(0));
children[2].ShiftBooksLeftInto(0);
}
private void RotateRight0To1(Node23 parent){
Node23[] children = parent.Children;
children[1].AddBookList(parent.RemoveLeftMostBookList());
parent.AddBookList(children[0].RemoveRightMostBookList());
}
private void RotateRight1To2(Node23 parent){
Node23[] children = parent.Children;
children[2].AddBookList(parent.RemoveRightMostBookList());
parent.AddBookList(children[1].RemoveRightMostBookList());
}
private void BalanceNodeUnderflow(Node23 n){
Node23 leaf;
int emptyPosition = n.FirstNullBookList();
if(!n.IsLeaf()){
leaf = GetSuccessorLeaf(n, emptyPosition);
n.AddBookList(leaf.RemoveBookList(0));
}
else{
leaf = n;
}
if(leaf.GetSize() == 0){
FillHole(leaf);
}
}
private void RedistributeParent3(Node23 hole, int holePosition){
Node23 parent = hole.Parent;
Node23[] siblings = parent.Children;
switch(holePosition){
case 0:
if(siblings[1].GetSize() == 2){
RotateLeft1To0(parent);
if(!hole.IsLeaf()){
hole.AddChildAt(1, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
}
}
else if(siblings[2].GetSize() == 2){
RotateLeft1To0(parent);
RotateLeft2To1(parent);
if(!hole.IsLeaf()){
hole.AddChildAt(1, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
siblings[2].ShiftChildrenLeftInto(0);
}
}
else{
RotateLeft1To0(parent);
hole.AddBookList(parent.RemoveBookList(0));
parent.ShiftBooksLeftInto(0);
siblings[1].AddBookList(siblings[2].RemoveBookList(0));
if(!hole.IsLeaf()){
hole.AddChildAt(1, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
hole.AddChildAt(2, siblings[1].RemoveLeftMostChild());
siblings[1].AddChildAt(0, siblings[2].RemoveLeftMostChild());
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
}
parent.RemoveRightMostChild();
}
break;
case 1:
if(siblings[0].GetSize() == 2){
RotateRight0To1(parent);
if(!hole.IsLeaf()){
siblings[1].ShiftChildrenRightInto(1);
siblings[1].AddChildAt(0, siblings[0].RemoveRightMostChild());
}
}
else if(siblings[2].GetSize() == 2){
RotateLeft2To1(parent);
if(!hole.IsLeaf()){
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
siblings[2].ShiftBooksLeftInto(0);
}
}
else{
RotateLeft2To1(parent);
siblings[1].ShiftBooksLeftInto(0);
RotateLeft1To0(parent);
parent.ShiftBooksLeftInto(0);
if(!hole.IsLeaf()){
siblings[0].AddChildAt(2, siblings[1].RemoveLeftMostChild());
siblings[1].AddChildAt(0, siblings[2].RemoveLeftMostChild());
siblings[1].AddChildAt(1, siblings[2].RemoveRightMostChild());
}
parent.RemoveRightMostChild();
}
break;
case 2:
if(siblings[0].GetSize() == 2){
RotateRight1To2(parent);
RotateRight0To1(parent);
if(!hole.IsLeaf()){
siblings[2].ShiftChildrenRightInto(1);
siblings[2].AddChildAt(0, siblings[1].RemoveRightMostChild());
siblings[1].ShiftBooksRightInto(1);
siblings[1].AddChildAt(0, siblings[0].RemoveRightMostChild());
}
}
else if(siblings[1].GetSize() == 2){
RotateRight1To2(parent);
if(!hole.IsLeaf()){
siblings[2].ShiftChildrenRightInto(1);
siblings[2].AddChildAt(0, siblings[1].RemoveRightMostChild());
}
}
else{
RotateLeft1To0(parent);
siblings[1].AddBookList(parent.RemoveRightMostBookList());
if(!hole.IsLeaf()){
siblings[0].AddChildAt(2, siblings[1].RemoveLeftMostChild());
siblings[1].ShiftChildrenLeftInto(0);
siblings[1].AddChildAt(1, siblings[2].RemoveLeftMostChild());
}
parent.RemoveRightMostChild();
}
break;
default:
break;
}
}
private void RedistributeParent2(Node23 hole, int holePosition){
Node23 parent = hole.Parent;
Node23[] siblings = parent.Children;
switch(holePosition){
case 0:
hole.AddBookList(parent.RemoveBookList(0));
parent.AddBookList(siblings[1].RemoveBookList(0));
siblings[1].ShiftBooksLeftInto(0);
break;
case 1:
hole.AddBookList(parent.RemoveBookList(0));
parent.AddBookList(siblings[0].RemoveBookList(1));
break;
default:
break;
}
}
private void Merge(Node23 hole, int holePosition){
Node23 parent = hole.Parent;
Node23[] sibling = parent.Children;
if(holePosition == 0){
sibling[0].AddBookList(sibling[1].RemoveBookList(0));
}
sibling[0].AddBookList(parent.RemoveBookList(0));
if(!hole.IsLeaf()){
sibling[0].AddChildAt(1, sibling[1].RemoveLeftMostChild());
sibling[0].AddChildAt(2, sibling[1].RemoveRightMostChild());
}
parent.RemoveRightMostChild();
if(parent.GetSize() == 0){
BalanceNodeUnderflow(parent);
}
}
private void FillHole(Node23 hole){
Node23[] siblings;
Node23 parent;
int holePosition;
if(hole == Root){
Root = hole.Children[0];
}else{
parent = hole.Parent;
siblings = parent.Children;
holePosition = hole.WhichChildAmI();
if(parent.GetSize() == 2){
RedistributeParent3(hole, holePosition);
}
else{
if(siblings[0].GetSize() == 2 || siblings[1].GetSize() == 2){
RedistributeParent2(hole, holePosition);
}else{
Merge(hole, holePosition);
}
}
}
}
}
package tree23;
import bookClasses.*;
/**
* #Node
*This Node is designed for a 2-3 Tree.
*The Node holds two Book objects and points to three children nodes of the same type.
*The node is also designed to hold an overflow Book and overflow child, until the node is split.
*/
public class Node23 {
public BookList[] Books;
private boolean isLeaf;
private int size;
public Node23 Parent;
public Node23[] Children;
//Constructors
public Node23(boolean isleaf){
Books = new BookList[3];
Children = new Node23[4];
isLeaf = isleaf;
size = 0;
}
public Node23[] SplitNode(){
Node23[] splitNodes = new Node23[2];
splitNodes[0] = new Node23(isLeaf);
splitNodes[1] = new Node23(isLeaf);
splitNodes[0].Parent = Parent;
splitNodes[1].Parent = Parent;
splitNodes[0].AddBookList(RemoveLeftMostBookList());
splitNodes[1].AddBookList(RemoveRightMostBookList());
if(!isLeaf){
Children[0].Parent = splitNodes[0];
Children[1].Parent = splitNodes[0];
splitNodes[0].Children[0] = Children[0];
splitNodes[0].Children[1] = Children[1];
Children[2].Parent = splitNodes[1];
Children[3].Parent = splitNodes[1];
splitNodes[1].Children[0] = Children[2];
splitNodes[1].Children[1] = Children[3];
}
return splitNodes;
}
//Book Functions
public int FirstNullBookList(){
int emptyPos = -1;
for(int i = 0; i < 2; i++){
if(Books[i] == null){
emptyPos = -1;
}
}
return emptyPos;
}
public int GetNextChildByKey(String key){
int nextChild = -1;
if(!isLeaf){
if(size == 1){
if(Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else{
nextChild = 1;
}
}
else{
if(Books[0].CompareTo(key) > 0){
nextChild = 0;
}
else if(Books[1].CompareTo(key) > 0){
nextChild = 1;
}
else{
nextChild = 2;
}
}
}
return nextChild;
}
public int GetMatchingBookListByKey(String key){
int match = -1;
for(int i = 0; i < size; i++){
if(Books[i].CompareTo(key) == 0)
match = i;
}
return match;
}
public void TakeAllBookLists(Node23 n){
for(int i = 0; i < 3; i++){
if(n.Books[i] != null){
AddBookList(n.RemoveBookList(i));
}
}
}
public void ShiftBooksRightFrom(int shiftStart){
for(int i = 2; i > shiftStart; i--){
Books[i] = Books[i - 1];
}
Books[shiftStart] = null;
}
public void ShiftBooksRightInto(int shiftEnd){
for(int i = shiftEnd; i > 0; i--){
Books[i] = Books[i - 1];
}
Books[0] = null;
}
public void ShiftBooksLeftFrom(int shiftStart){
for(int i = 0; i < shiftStart; i++){
Books[i] = Books[i+1];
}
Books[shiftStart] = null;
}
public void ShiftBooksLeftInto(int shiftEnd){
for(int i = shiftEnd; i < 2; i++){
Books[i] = Books[i + 1];
}
Books[2] = null;
}
public void AddBookList(BookList newBookList){
if(size == 0){
Books[0] = newBookList;
}
else{
if(newBookList.CompareTo(Books[0]) < 0){
ShiftBooksRightFrom(0);
Books[0] = newBookList;
}
else{
if(size == 1){
Books[1] = newBookList;
}
else{
if(newBookList.CompareTo(Books[1]) < 0){
ShiftBooksRightFrom(1);
Books[1] = newBookList;
}
else{
Books[2] = newBookList;
}
}
}
}
size++;
}
public void AddBook(Book newBook, String key){
if(size == 0){
AddBookList(new BookList(newBook, key));
}
else{
int match = GetMatchingBookListByKey(key);
if(match != -1){
Books[match].AddBook(newBook);
}
else{
AddBookList(new BookList(newBook, key));
}
}
}
public BookList RemoveRightMostBookList(){
BookList bList = null;
for(int i = 2; i > 0; i--){
if(Books[i] != null){
bList = Books[i];
Books[i] = null;
size--;
break;
}
}
return bList;
}
public BookList RemoveLeftMostBookList(){
BookList bList = null;
bList = Books[0];
ShiftBooksLeftInto(0);
size--;
return bList;
}
public BookList RemoveBookList(int position){
BookList bList = Books[position];
ShiftBooksLeftInto(position);
size--;
return bList;
}
public void RemoveMatchingBook(Book b, String key){
if(Books[0] != null){
if(Books[0].CompareTo(key) == 0){
Books[0].DeleteBooksByISSN(b.ISSN);
}
}
else if(Books[1] != null){
if(Books[1].CompareTo(key) == 0){
Books[1].DeleteBooksByISSN(b.ISSN);
}
}
else if(Books[2] != null){
if(Books[2].CompareTo(key) == 0){
Books[2].DeleteBooksByISSN(b.ISSN);
}
}
}
//Child-Node Functions
public Node23 RemoveLeftMostChild(){
Node23 n = null;
int i = 0;
while(n == null && i <= 3){
if(Children[i] != null){
n = Children[i];
Children[i] = null;
}
i++;
}
return n;
}
public Node23 RemoveRightMostChild(){
Node23 n = null;
int i = 3;
while(n == null && i >= 0 ){
if(Children[i] != null){
n = Children[i];
Children[i] = null;
}
i--;
}
return n;
}
public void AddChildAt(int index, Node23 newChildNode){
Children[index] = newChildNode;
}
public void AddSplitNodeChildAt(int position, Node23[] splitNode){
ShiftChildrenRightFrom(position + 1);
AddChildAt(position, splitNode[0]);
AddChildAt(position + 1, splitNode[1]);
}
public void ShiftChildrenRightFrom(int shiftStart){
for(int i = 3; i > shiftStart; i--){
Children[i] = Children[i - 1];
}
Children[shiftStart] = null;
}
public void ShiftChildrenRightInto(int shiftEnd){
for(int i = shiftEnd; i > 0; i--){
Children[i] = Children[i - 1];
}
Children[0] = null;
}
public void ShiftChildrenLeftFrom(int shiftStart){
for(int i = 0; i < shiftStart; i++){
Children[i] = Children[i + 1];
}
Children[shiftStart] = null;
}
public void ShiftChildrenLeftInto(int shiftEnd){
for(int i = shiftEnd; i < 2; i++){
Children[i] = Children[i + 1];
}
Children[2] = null;
}
//Attribute Functions
public int CountChildren(){
int count = 0;
for(int i = 0; i < 3; i++){
if(Children[i] != null){
count++;
}
}
return count;
}
public boolean IsRoot(){
boolean isRoot = false;
if(Parent == null){
isRoot = true;
}
return isRoot;
}
public int WhichChildAmI(){
int childNum = -1;
if(!IsRoot()){
for(int i = 0; i < Parent.size + 1; i++){
if(Parent.Children[i] == this){
childNum = i;
}
}
}
return childNum;
}
public boolean IsLeaf(){
return isLeaf;
}
public int GetSize(){
return size;
}
}
Class Book: This is the Book class that makes the links of the linked list within each Node23
package bookClasses;
public class Book{
public int ISSN;
public String Title;
public String[] Author;
public Book Next;
public Book(){}
/**
* #param ISSN
* #param Title
* #param Author
*/
public Book(int issn, String title, String author){
ISSN = issn;
Title = title;
Author = author.split(",");
Next = null;
}
private String AuthorToString(){
String author = Author[0];
if(Author.length == 2){
author = author + ", " + Author[1];
}
return author;
}
public void Display(){
System.out.println("\tISSN: " + ISSN);
System.out.println("\tTITLE: " + Title);
System.out.println("\tAUTHOR: " + AuthorToString());
}
public boolean MatchAuthor(String author){
boolean match = false;
if(Author.length == 2){
if(author.compareTo(Author[0].toLowerCase()) == 0
|| author.compareTo(Author[1].toLowerCase()) == 0){
match = true;
}
}
if(author.split(",") == Author){
match = true;
}
return match;
}
}
Class BookList: This is the linked List inside of each node containing copies all books with a matching key
package bookClasses;
public class BookList {
public String Key;
public Book Head;
private int Size;
public BookList(){
Head = null;
Size = 0;
};
public BookList(Book b, String key){
Size = 1;
Key = key;
Head = b;
}
//Insert Functions
public void AddBook(Book newBook){
newBook.Next = Head;
Head = newBook;
Size++;
}
//Search Functions
public BookList GetBooksByISSN(int issn){
BookList books = new BookList();
Book b = Head;
for(int i = 0; i < Size; i++){
if(issn == b.ISSN){
books.AddBook(b);
}
}
return books;
}
public BookList GetBooksByTitle(String title){
BookList matches = new BookList();
Book b = Head;
for(int i = 0; i < Size; i++){
if(title.compareTo(b.Title.toLowerCase()) == 0){
matches.AddBook(b);
}
}
return matches;
}
public BookList GetBooksByAuthor(String author){
BookList books = new BookList();
Book b = Head;
for(int i = 0; i < Size; i++){
if(b.MatchAuthor(author)){
books.AddBook(b);
}
b = b.Next;
}
return books;
}
//Delete Functions
public void DeleteBooksByAuthor(String author){
Book b = Head;
if(b.MatchAuthor(author)){
Head = b.Next;
Size--;
}
else{
while(b.Next != null){
if(b.Next.MatchAuthor(author)){
b.Next = b.Next.Next;
Size--;
}
else{
b = b.Next;
}
}
}
}
public void DeleteBooksByTitle(String title){
Book b = Head;
if(b.Title.toLowerCase().compareTo(title.toLowerCase()) == 0){
Head = b.Next;
Size--;
}
else{
while(b.Next != null){
if(b.Next.Title.toLowerCase().compareTo(title.toLowerCase()) == 0){
b.Next = b.Next.Next;
Size--;
}
else{
b = b.Next;
}
}
}
}
public void DeleteBooksByISSN(int issn){
Book b = Head;
if(b.ISSN == issn){
Head = b.Next;
Size--;
}
else{
while(b.Next != null){
if(b.Next.ISSN == issn){
b.Next = b.Next.Next;
Size--;
}
else{
b = b.Next;
}
}
}
}
//Other Methods
public void Displayall(){
Book b = Head;
for(int i = 0; i < Size; i++){
b.Display();
b = b.Next;
}
}
public int CompareTo(BookList bookList){
return (Key.compareTo(bookList.Key));
}
public int CompareTo(String key){
return (Key.compareTo(key));
}
public int Size(){
return Size;
}
}
Heres the input file - the 1 specifies INSERT
1
60
The Black Dahlia
James,Ellroy
1
98
The Turn of the Screw
Henry,James
1
147
The Wings of the Dove
Henry,James
1
151
A Portrait of the Artist as a Young Man
James,Joyce
1
157
The Postman Always Rings Twice
James,M.
1
184
How Late It Was, How Late
James,Kelman
1
186
A Disaffection
James,Kelman
1
320
The Ambassadors
Henry,James
1
326
What Maisie Knew
Henry,James
1
327
The Golden Bowl The Golden Bowl
Henry,James
1
353
The Charwoman's Daughter
James,Stephens
1
362
Ulysses
James,Joyce
1
478
Finnegans Wake
James,Joyce
After inserting ulysses
The Black Dahlia
The Turn of the Screw
The Wings of the Dove
A Portrait of the Artist as a Young Man
The Postman Always Rings Twice
How Late It Was, How Late
A Disaffection
The Ambassadors
What Maisie Knew
The Golden Bowl The Golden Bowl
The Charwoman's Daughter
Ulysses <==Head
Now here's where it gets wacky:
if I try and insert this entry:
478
Finnegans Wake
James,Joyce
bringing the size of the list from 12, to 13,
the new order of the list becomes:
The Black Dahlia
The Turn of the Screw
The Wings of the Dove
A Portrait of the Artist as a Young Man
The Postman Always Rings Twice
How Late It Was, How Late
A Disaffection
The Ambassadors
What Maisie Knew
The Golden Bowl The Golden Bowl
Ulysses
Finnegans Wake <=======HEAD
The Charwomans daughter has dissappeared.
This change happens when Head = newBook;
So, I thought it might have something to do with my hardware, and the computer I originally had this project stored on uses an AMD processor, so I got on my intel laptop and accessed the AMD desktop over the network. I copied the project file into my workspace on the laptop - Just a simple drag and drop.
First I run the code on the intel laptop,, and as expected, it doesnt work, then I run the code on the desktop again, and NOW IT WORKS. No changes were made.
After the code worked on the desktop, it suddenly worked on the laptop.
Related
I have an assignment for my Data Structures class. In the assignment, we have to implement polynomial addition using linked lists. I think I have it down but eclipse is giving me a null pointer exception. My problem is with the add method, though I included the whole class for context. Multiply I will tackle after.. Please help.
class PolynomialLinkedList{
private static class PNode{
private int coe;
private int exp;
private PNode next;
public PNode(int c, int e){
this(c, e, null);
}
public PNode(int c, int e, PNode n){
coe = c;
exp = e;
next = n;
}
public void setCoe(int c){ coe = c;}
public void setExp(int e){ exp = e;}
public void setNext(PNode n){ next = n;}
public int getCoe(){ return coe;}
public int getExp(){ return exp;}
public PNode getNext(){ return next;}
}
private PNode first;
private PNode last;
public PolynomialLinkedList(){
first = last = null;
}
public PolynomialLinkedList(int c, int e){
PNode tempn = new PNode(c, e);
first = last = tempn;
}
public void print(){
if (first == null){
System.out.println();
return;
}
PNode temp = first;
String ans = "";
while (temp != null){
if (temp.getCoe() > 0) {
if (temp != first) ans = ans + " + ";
ans = ans + temp.getCoe();
}
else if (temp.getCoe() < 0) ans = ans + " - " + temp.getCoe() * -1;
if (temp.getExp() != 0){
ans = ans + "X^" + temp.getExp();
}
temp = temp.getNext();
}
System.out.println(ans);
}
public PolynomialLinkedList add(PolynomialLinkedList s){
PolynomialLinkedList sum = new PolynomialLinkedList();
PNode temp1 = this.first;
PNode temp2 = s.first;
PNode tempAns = new PNode(0,0);
if(temp1.exp != temp2.exp) {
while(temp1.exp > temp2.exp) {
tempAns.setCoe(temp1.coe);
tempAns.setExp(temp1.exp);
temp1 = temp1.getNext();
tempAns = sum.first.getNext();
}
while(temp1.exp < temp2.exp) {
tempAns.setCoe(temp2.coe);
tempAns.setExp(temp2.exp);
temp2 = temp2.getNext();
tempAns = sum.first.getNext();
}
}
else if(temp1.exp == temp2.exp) {
while(temp1.exp == temp2.exp) {
tempAns.setCoe((temp1.coe + temp2.coe));
tempAns.setExp(temp1.exp);
temp1 = temp1.getNext();
temp2 = temp2.getNext();
tempAns = sum.first.getNext();
}
}
return sum;
}
public PolynomialLinkedList multiply(PolynomialLinkedList s){
PolynomialLinkedList product = new PolynomialLinkedList();
//implement this method
return product;
}
}
I am trying to implement a tree B on my own, the insert_order was working, and the function divide, but the search function, I don't know how to implement it to give me the left child of the node key.
This is the method that the node finds, if it doesn't find it it returns -1, but I want it to return the position of the continuous key (if it can't find it and it's leaf).
public int search(Nodo nodo, int valor){
int i = 0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i + 1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return i;
}
if(nodo.isLeaf()){
return -1;
}else{
return search(nodo.sons[i], valor);
}
}
This method inserts in an orderly way in the array,moves a position to reorder the array
public void insert_order(Nodo nodo, int value, Nodo right_son){
if(estaVacia(nodo.keys)){
nodo.keys[nodo.numKeys] = value;
nodo.sons[1] = right_son;
nodo.numSons++;
}else{
int pivote = 0;
while(pivote < nodo.numKeys&&nodo.keys[pivote] < value){
pivote = pivote + 1;
}
for(int i = nodo.numKeys-1; i >= pivote; --i ){
nodo.keys[i+1] = nodo.keys[i];
}
for(int i = nodo.numSons-1; i >= pivote; --i){
nodo.sons[i+1] = nodo.sons[i];
}
nodo.keys[pivote] = value;
nodo.sons[pivote+1] = right_son;
}
nodo.numKeys++;
if(!nodo.isLeaf()){
nodo.numSons++;
}
}
this is a method that inserts a key into the tree, if it is a leaf it calls insert_order, but if it is not a leaf it calls recursively until reaching a leaf, if it reaches a leaf it should call insert_order.
public Nodo insertion(Nodo nodo, int value){
if(nodo.isLeaf()){
insert_order(nodo, value, null);
}else{
int i = search(nodo,value);
Nodo nuevo = null;
if(i!=-1){//<-- is leaf and return -1 :(
throw new RuntimeException("exist this key");
}else{
//error: Array index of bounds Exception : -1
nuevo = insertion(nodo.sons[i], value);
}
if(nuevo != null){
int pivote = nuevo.keys[0];
insert_order(nodo, pivote, nuevo);
for(int k = 0; k <= nodo.numKeys-1; k++ ){
nodo.keys[k] = nodo.keys[k+1];
}
}
}
if (nodo.numKeys > nodo.degree -1){
Nodo new1 = divide(nodo);
/*
* the root was divided, the new node will be the right child
* and all that remains is to upload the root to the father,
* but since this is the first time, the root will divide and
* redefine the root.
*
* */
if(first_time && new1 != null ){
int pivote1 = new1.keys[0];
Nodo izquierda = nodo;
Nodo new_root = new Nodo(root.degree);
new_root.keys = new int [root.degree];
new_root.sons = new Nodo[root.degree];
insert_order(new_root,pivote1, new1);
root = new_root;
int pivotem = 0;
while(root.keys[pivotem] < pivote1){
pivotem = pivotem + 1;
}
root.sons[pivotem] = izquierda;
for(int k = 0; k <= new1.numKeys-1; k++ ){
new1.keys[k] = new1.keys[k+1];
}
new1.numKeys--;
first_time = false;
}
return new1;
}else{
return null;
}
}
I leave all the code in case someone wants to see it in more detail
package ARBOL_B;
public class treeB {
Nodo root;
public treeB(int grado){
root = new Nodo(grado);
}
public boolean exist(Nodo nodo, int valor){
int i =0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i+1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return true;
}
if(nodo.isLeaf()){
return false;
}else{
return exist(nodo.sons[i], valor);
}
}
/*
This is the method that the node finds, if it doesn't find it it returns -1, but I want it to return the position of the continuous key (if it can't find it and it's leaf).
* */
public int search(Nodo nodo, int valor){
int i = 0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i + 1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return i;
}
if(nodo.isLeaf()){
return -1;
}else{
return search(nodo.sons[i], valor);
}
}
/*
This method inserts in an orderly way in the array,
moves a position to reorder the array
*/
public void insert_order(Nodo nodo, int value, Nodo right_son){
if(estaVacia(nodo.keys)){
nodo.keys[nodo.numKeys] = value;
nodo.sons[1] = right_son;
nodo.numSons++;
}else{
int pivote = 0;
while(pivote < nodo.numKeys&&nodo.keys[pivote] < value){
pivote = pivote + 1;
}
for(int i = nodo.numKeys-1; i >= pivote; --i ){
nodo.keys[i+1] = nodo.keys[i];
}
for(int i = nodo.numSons-1; i >= pivote; --i){
nodo.sons[i+1] = nodo.sons[i];
}
nodo.keys[pivote] = value;
nodo.sons[pivote+1] = right_son;
}
nodo.numKeys++;
if(!nodo.isLeaf()){
nodo.numSons++;
}
}
boolean first_time = true;
/*
this is a method that inserts a key into the tree,
if it is a leaf it calls insert_order, but if it is not a leaf it
calls recursively until reaching a leaf, if it reaches a leaf
it should call insert_order
* */
public Nodo insertion(Nodo nodo, int value){
if(nodo.isLeaf()){
insert_order(nodo, value, null);
}else{
int i = search(nodo,value);
Nodo nuevo = null;
if(i!=-1){//<-- is leaf and return -1 :(
throw new RuntimeException("exist this key");
}else{
//error: Array index of bounds Exception : -1
nuevo = insertion(nodo.sons[i], value);
}
if(nuevo != null){
int pivote = nuevo.keys[0];
insert_order(nodo, pivote, nuevo);
for(int k = 0; k <= nodo.numKeys-1; k++ ){
nodo.keys[k] = nodo.keys[k+1];
}
}
}
if (nodo.numKeys > nodo.degree -1){
Nodo new1 = divide(nodo);
/*
* the root was divided, the new node will be the right child
* and all that remains is to upload the root to the father,
* but since this is the first time, the root will divide and
* redefine the root.
*
* */
if(first_time && new1 != null ){
int pivote1 = new1.keys[0];
Nodo izquierda = nodo;
Nodo new_root = new Nodo(root.degree);
new_root.keys = new int [root.degree];
new_root.sons = new Nodo[root.degree];
insert_order(new_root,pivote1, new1);
root = new_root;
int pivotem = 0;
while(root.keys[pivotem] < pivote1){
pivotem = pivotem + 1;
}
root.sons[pivotem] = izquierda;
for(int k = 0; k <= new1.numKeys-1; k++ ){
new1.keys[k] = new1.keys[k+1];
}
new1.numKeys--;
first_time = false;
}
return new1;
}else{
return null;
}
}
public Nodo divide(Nodo nodo){
Nodo new_node = new Nodo(nodo.degree);
new_node.keys = new int[nodo.degree];
new_node.sons = new Nodo[nodo.degree];
for(int i = (int)(Math.ceil(nodo.degree/2)), j = 0; i < nodo.degree; i++, j++){
new_node.keys[j] = nodo.keys[i];
nodo.keys[i] = 0;
if(!nodo.isLeaf()){
new_node.sons[j+1] = nodo.sons[i+1];
nodo.sons[i+1] = null;
}
}
if(nodo.isLeaf()){
nodo.numKeys = (int)(Math.ceil(nodo.degree/2));
new_node.numKeys = nodo.degree - nodo.numKeys;
}
return new_node;
}
public boolean estaVacia(int[] claves){
for(int i = 0; i < root.numKeys; i++){
if(claves[i] != 0){
return false;
}
}
return true;
}
public static String print(int[] list){
String str = "";
for(int i = 0;i < list.length; i++){
str += list[i]+ "; ";
}
return str;
}
public static void printSons(Nodo[] sons){
String str = "";
for(int i = 0; i < sons.length; i ++ ){
if(sons[i] != null)
str += " [ "+print(sons[i].keys)+ " ] , ";
}
System.out.println(str);
}
public static void main(String[] args) {
treeB bb = new treeB(3);
bb.root.keys = new int[3];
bb.root.sons = new Nodo[3];
Nodo nuevo = bb.insertion(bb.root, 3);
System.out.println(print(bb.root.keys));
nuevo = bb.insertion(bb.root, 1);
System.out.println(print(bb.root.keys));
System.out.println(bb.root.numKeys);
System.out.println(bb.root.numSons);
nuevo = bb.insertion(bb.root, 2);
System.out.print(bb.root.numSons+"<");
System.out.print(bb.root.sons[1].numKeys);
nuevo = bb.insertion(bb.root, 4);
System.out.println(print(bb.root.keys));
printSons(bb.root.sons);
}
}
And this is the class Node.
public class Nodo {
int degree;
int []keys = new int[degree];// es hasta N-1, pero se necesita un espacio mas
int numKeys = 0;
Nodo[] sons = new Nodo[degree];
int numSons = 0;
public Nodo(int grado){
this.degree = grado;
}
public Nodo(){ }
public boolean isLeaf(){
for(int i = 0 ; i < this.numSons; i++){
if(this.sons[i] != null){
return false;
}
}
return true;
}
}
I hope you can help me, I do not know how to get me to return the right key, and if someone has a better way of doing it I would appreciate your support, Thanks in advance. :)
I managed to implement the search method, my solution was to return the current Node, instead of a position, I made a class that packed the Node and the position in the key array, that is if it can't find it.
public wrapp search_2(Node node, int valor){
wrapp em;
int i = 0;
while(i < node.numKeys && node.keys[i] < valor){
i = i + 1;
}
if(i < node.numKeys && node.keys[i] == valor){
em = new wrapp(null,-1);
return em;
}
if(node.isLeaf()){
em = new wrapp(node,i);
return em;
}else{
return search_2(node.sons[i], valor);
}
}
The problem was finding the current node, thinking that it would return the position of the child,when in reality it would be much easier to return the same node
The error I believe starts on line 102: int treeDepth(Node Node) because when I run the code with a regular while loop with a count, it runs and displays a tree. But as soon as I change the while condition to while (treeDepth(this.root) <= 5) it runs but displays nothing, and I get no errors. Trying to make it so the tree that is created doesn't have a depth larger than 5.
import java.io.*;
import java.util.*;
class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
right = null;
left = null;
}
}
public class treeStructureBinary{
Node root;
public static void main(String[] args) {
treeStructureBinary bn =new treeStructureBinary();
bn.appMain(args);
}
void appMain(String[] args) {
createBinaryTree();
}
private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
return current;
}
return current;
}
public void add(int value) {
this.root = addRecursive(this.root, value);
}
public treeStructureBinary createBinaryTree() {
treeStructureBinary bt = new treeStructureBinary();
int [] array = new int[89];
int counter = 0;
boolean check = true;
while (treeDepth(this.root) <= 5)
{
Random rand = new Random();
int n = rand.nextInt(89) + 10;
for(int z = 0; z <= counter; z++)
{
if ( n == array[z])
{
check = false;
break;
}
}
if (check == true)
{
bt.add(n);
array[counter] = n;
counter++;
}
check = true;
}
bt.traverseLevelOrder();
return bt;
}
public void traverseLevelOrder() {
if (this.root == null) {
return;
}
Queue<Node> nodes = new LinkedList<>();
nodes.add(this.root);
while (!nodes.isEmpty()) {
Node node = nodes.remove();
System.out.print(" " + node.value);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
nodes.add(node.right);
}
}
}
int treeDepth(Node Node){
if (Node == null) {
return 0;
}else {
int lDepth = treeDepth(Node.left);
int rDepth = treeDepth(Node.right);
if (lDepth > rDepth) {
System.out.println("lDepth" + "\n");
return (lDepth + 1);
}else {
System.out.println("rDepth" + "\n");
return (rDepth + 1);
}
}
}
}
I think your addRecursive never actually adds the node to the tree--or always adds it? Anyway it looks funky. I'd focus on that for a bit.
This code in particular:
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
return current;
}
always forces an assign (even if it's not a leaf) and the final else will only execute when value == current.value which is probably not what you want.
I don't really want to go much further because it looks homeworky and you'll gain more figuring it out yourself.
It might work anyway (You just may be re-assigning every node at every level) but I'm not sure without running it.
Anyway, if this is a homework assignment I'd really like to commend you on your style, it's one of the best I've seen posted here for a homework-like question.
Main problem here is that you are working on two different trees.
First you create one tree in main function:
public static void main(String[] args) {
treeStructureBinary bn =new treeStructureBinary();
bn.appMain(args);
}
Then you create another one in createBinaryTree method:
public SthApplication createBinaryTree() {
treeStructureBinary bt = new treeStructureBinary();
See, you used new keyword twice, so there will be two objects.
Later in your app you refer to this.root (which is the one from main), but some methods use local variable bt.
In example, treeDepth(this.root) operates on different tree then the bt.add(n), so it goes into infinite loop.
If you solve that problem, you will know how to finish the rest.
Thanks guys I figured it out!
import java.io.*;
import java.util.*;
class Node {
int value;
int balancefactor;
int nodex;
Node left;
Node right;
Node(int value, int balancefactor, int nodex) {
this.value = value;
this.balancefactor = balancefactor;
this.nodex = nodex;
this.right = null;
this.left = null;
}
}
public class treeStructureBinary{
Node root;
public static void main(String[] args) {
treeStructureBinary bn =new treeStructureBinary();
bn.appMain(args);
}
void appMain(String[] args) {
int count = args.length;
if (count >1) {
count = 1;
}
String [] cmdln = {""};
for (int i=0;i<count;i++) {
cmdln[i]=args[i];
}
if (cmdln[0].equals("BT")){
createBinaryTree();
} else if (cmdln[0].equals("AVL")) {
} else {
System.out.println("Please enter BT or AVL to choose the type of
tree.");
}
}
private Node addRecursive(Node current, int value, int balancefactor, int
nodex) {
if (current == null) {
return new Node(value, balancefactor, nodex);
} if (value < current.value) {
balancefactor++;
nodex=(nodex*2);
current.left = addRecursive(current.left, value, balancefactor,
nodex);
} else if (value > current.value) {
balancefactor++;
nodex=(nodex*2)+1;
current.right = addRecursive(current.right, value, balancefactor,
nodex);
} else {
return current;
}
return current;
}
public void add(int value) {
int balancefactor=1;
int nodex=0;
this.root = addRecursive(this.root, value, balancefactor, nodex);
}
public treeStructureBinary createBinaryTree() {
treeStructureBinary bt = new treeStructureBinary();
int [] array = new int[89];
int counter = 0;
boolean check = true;
int temp = 0;
while (temp < 5) {
Random rand = new Random();
int n = rand.nextInt(89) + 10;
for(int z = 0; z <= counter; z++) {
if ( n == array[z]) {
check = false;
break;
}
}
if (check == true) {
bt.add(n);
array[counter] = n;
counter++;
}
check = true;
temp = bt.treeDepth();
}
bt.traverseLevelOrder();
Scanner reader =new Scanner(System.in);
System.out.println("\n\nEnter a number to delete or 0 to exit");
int input = reader.nextInt();
Boolean isMatch = true;
while (input!=0) {
for(int p = 0; p < counter; p++)
{
//System.out.println(array[p]);
if (input != array[p])
{
isMatch = false;
}
else
{
isMatch = true;
array[p] = 0;
break;
}
}
if (isMatch == false )
{
System.out.println("Error, number not found.");
}
bt.nodeDelete(input);
bt.traverseLevelOrder();
System.out.println("\n\nEnter a number to delete or 0 to exit");
input = reader.nextInt();
}
return bt;
}
public void traverseLevelOrder() {
int count = 0;
int outer = 31;
int inner = 30;
int lastnode= 0;
int check = 0;
if (this.root == null) {
return;
}
Queue<Node> nodes = new LinkedList<>();
nodes.add(this.root);
while (!nodes.isEmpty()) {
Node node = nodes.remove();
if (count < node.balancefactor) {
System.out.print("\n");
for (int i=0; i<outer; i++) {
System.out.print(" ");
}
inner=outer;
outer=outer/2;
count++;
lastnode=0;
check=0;
}
check=((node.nodex-lastnode));
for (int i=0; i<(inner*check*2);i++) {
System.out.print(" ");
}
if (check >1) {
for (int j=0;j<check;j++) {
System.out.print(" ");
}
}
lastnode=node.nodex;
System.out.print(node.value);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
if (node.right==null &&lastnode == 0) {
if (count==5) {
break;
}
System.out.print(" ");
}
nodes.add(node.right);
}
}
}
int treeDepth(){
int temp = treeDepthRecursive(this.root);
return temp;
}
int treeDepthRecursive(Node current) {
if (current == null) {
return 0;
} else {
int lDepth = treeDepthRecursive(current.left);
int rDepth = treeDepthRecursive(current.right);
if (lDepth > rDepth) {
return (lDepth + 1);
} else {
return (rDepth + 1);
}
}
}
public void nodeDelete(int value) {
nodeDeleteRecursive(root, value);
}
public Node nodeDeleteRecursive(Node current, int value) {
if (current == null) {
return null;
}
if (value == current.value) {
if (current.left ==null && current.right==null) {
return null;
}
if (current.right==null) {
return current.left;
}
if (current.left==null) {
return current.right;
}
int sValue = findSmall(current.right);
current.value = sValue;
current.right = nodeDeleteRecursive(current.right, sValue);
return current;
}
if (value < current.value) {
current.left = nodeDeleteRecursive(current.left, value);
return current;
}
current.right =nodeDeleteRecursive(current.right, value);
return current;
}
public int findSmall(Node root) {
return root.left == null?(root.value):(findSmall(root.left));
}
}
How would I display this linked list in desending order by Score? I need it when it when I display it in my GUI to sort by the highest score at the top, and then desending to the lowest score in the bottom? Also, I was wondering if there is a way to limit the entries to only 10. Any help would be appreciated! Thanks.
public class ScoreList {
private Player head; //reference to the head of the list
private Player tail; //reference to the tail of the list
int count;
public ScoreList() {
count = 0;
head = null;
tail = null;
}
public int getCount() {
return count;
}
public int size() {
int count = 0;
Player p = head;
while(p != null) {
count++;
p = p.next;
}
return count;
}
//method to add an item to the list - append to the tail of the list
public void add(String name, String score) {
// Create Player object
Player newPlayer = new Player(name, score);
if (head == null) {
head = newPlayer;
tail = head;
count++;
}
else {
//append to the end of the list
tail.setNext(newPlayer);
tail = newPlayer;
count++;
}
if(size() > 10) {
Player currentPlayer = head;
for (int i = 0; i < 9; i++) {
currentPlayer = currentPlayer.next;
}
currentPlayer.next = null;
}
}
// end add method
//method to let the user get the data from a node in the list
public String getItem(int index) {
String result = "";
String name = "";
String score = "";
Player curName;
if (count > 0 && index == 0) {
//return the Player info at the head of the list
name = head.getName();
score = head.getScore();
}
else if (index > 0 && index < count) {
curName = head;
for (int i = 1; i <= index; i++) {
curName = curName.getNext();
}
name = curName.getName();
score = curName.getScore();
}
result = "Player: " + name + " Score: " + score;
return result;
}
//nested inner class
public class Player {
private String player;
private String score;
private Player next;
public Player() {
player = "";
score = "";
next = null;
}
public Player(String artist, String title) {
this.player = artist;
this.score = title;
next = null;
}
public String getName() {
return player;
}
public String getScore() {
return score;
}
public Player getNext() {
return next;
}
public void setArtist(String player) {
this.player = player;
}
public void setTitle(String score) {
this.score = score;
}
public void setNext(Player next) {
this.next = next;
}
}
}
Why are you taking Score as a String?
I am assuming score as Integer
below is the sort method that you can include in ScoreList class, which will sort your LinkList in descending order of player score.
Time Complexity : O(nlogn)
Space COmplexity: O(n)
Hope this helps
public void sort() {
Player runner = head;
Player[] arr = new Player[size()];
int i = 0;
while (runner != null) {
arr[i++] = runner;
runner = runner.next;
}
Arrays.sort(arr, new Comparator<Player>() {
public int compare(Player o1, Player o2) {
if (Integer.parseInt(o1.getScore()) > Integer.parseInt(o2.getScore())) {
return -1;
} else if (Integer.parseInt(o1.getScore()) < Integer.parseInt(o2.getScore())) {
return 1;
} else {
return 0;
}
}
});
for (int j = 0; j < arr.length - 1; j++) {
arr[j].setNext(arr[j + 1]);
}
if (arr.length > 0) {
arr[arr.length - 1].setNext(null);
head = arr[0];
tail = arr[arr.length - 1];
}
}
Greeting to everyone. I currently work on a program that sorting the emergency number of patients(the number that assigned by nurse when they enter the emergency room and this number determines the seriousness of their sickness too). However, if there are more than 1 patient who hold the same emergency numbers(eg: 2 patients hold emergency number 1), the one who came earlier should receive the treatment first. For this reason, I have 2 sortings, one is to sort the emergency number in ascending order and the other is to sort the time in ascending order too. But unfortunately the second sorting cannot work correctly.The following are the explanations for the type of emergency numbers:
Emergency number : 1 – Immediately life threatening
Emergency number : 2 – Urgent, but not immediately life threatening
Emergency number : 3 – Less urgent
So,now comes the coding part(Please note that this is a linkedlist)
Interface:
public interface ListInterface<T> {
public boolean add(T newEntry);
public boolean add(int newPosition, T newEntry);
public T remove(int givenPosition);
public void clear();
public boolean replace(int givenPosition, T newEntry);
public T getEntry(int givenPosition);
public boolean contains(T anEntry);
public int getLength();
public boolean isEmpty();
public boolean isFull();
}
LList class:
/**
* LList.java
* A class that implements the ADT list by using a chain of nodes,
* with the node implemented as an inner class.
*/
public class LList<T> implements ListInterface<T> {
private Node firstNode; // reference to first node
private int length; // number of entries in list
public LList() {
clear();
}
public final void clear() {
firstNode = null;
length = 0;
}
public boolean add(T newEntry) {
Node newNode = new Node(newEntry); // create the new node
if (isEmpty()) // if empty list
firstNode = newNode;
else { // add to end of nonempty list
Node currentNode = firstNode; // traverse linked list with p pointing to the current node
while (currentNode.next != null) { // while have not reached the last node
currentNode = currentNode.next;
}
currentNode.next = newNode; // make last node reference new node
}
length++;
return true;
}
public boolean add(int newPosition, T newEntry) { // OutOfMemoryError possible
boolean isSuccessful = true;
if ((newPosition >= 1) && (newPosition <= length+1)) {
Node newNode = new Node(newEntry);
if (isEmpty() || (newPosition == 1)) { // case 1: add to beginning of list
newNode.next = firstNode;
firstNode = newNode;
}
else { // case 2: list is not empty and newPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < newPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
newNode.next = nodeBefore.next; // make new node point to current node at newPosition
nodeBefore.next = newNode; // make the node before point to the new node
}
length++;
}
else
isSuccessful = false;
return isSuccessful;
}
public T remove(int givenPosition) {
T result = null; // return value
if ((givenPosition >= 1) && (givenPosition <= length)) {
if (givenPosition == 1) { // case 1: remove first entry
result = firstNode.data; // save entry to be removed
firstNode = firstNode.next;
}
else { // case 2: givenPosition > 1
Node nodeBefore = firstNode;
for (int i = 1; i < givenPosition - 1; ++i) {
nodeBefore = nodeBefore.next; // advance nodeBefore to its next node
}
result = nodeBefore.next.data; // save entry to be removed
nodeBefore.next = nodeBefore.next.next; // make node before point to node after the
} // one to be deleted (to disconnect node from chain)
length--;
}
return result; // return removed entry, or
// null if operation fails
}
public boolean replace(int givenPosition, T newEntry) {
boolean isSuccessful = true;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
// System.out.println("Trace| currentNode.data = " + currentNode.data + "\t, i = " + i);
currentNode = currentNode.next; // advance currentNode to next node
}
currentNode.data = newEntry; // currentNode is pointing to the node at givenPosition
}
else
isSuccessful = false;
return isSuccessful;
}
public T getEntry(int givenPosition) {
T result = null;
if ((givenPosition >= 1) && (givenPosition <= length)) {
Node currentNode = firstNode;
for (int i = 0; i < givenPosition - 1; ++i) {
currentNode = currentNode.next; // advance currentNode to next node
}
result = currentNode.data; // currentNode is pointing to the node at givenPosition
}
return result;
}
public boolean contains(T anEntry) {
boolean found = false;
Node currentNode = firstNode;
while (!found && (currentNode != null)) {
if (anEntry.equals(currentNode.data))
found = true;
else
currentNode = currentNode.next;
}
return found;
}
public int getLength() {
return length;
}
public boolean isEmpty() {
boolean result;
if (length == 0)
result = true;
else
result = false;
return result;
}
public boolean isFull() {
return false;
}
public String toString() {
String outputStr = "";
Node currentNode = firstNode;
while (currentNode != null) {
outputStr += currentNode.data + "\n";
currentNode = currentNode.next;
}
return outputStr;
}
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
this.next = null;
}
private Node(T data, Node next) {
this.data = data;
this.next = next;
}
} // end Node
} // end LList
Patient class:
public class Patient {
private int emergencyNo;
private int queueTime;
private String patientName;
private String patientIC;
private String patientGender;
private String patientTelNo;
private String patientAdd;
private String visitDate;
public Patient() {
}
public Patient(int emergencyNo, int queueTime, String patientName, String patientIC, String patientGender, String patientTelNo, String patientAdd, String visitDate)
{
this.emergencyNo = emergencyNo;
this.queueTime = queueTime;
this.patientName = patientName;
this.patientIC = patientIC;
this.patientGender = patientGender;
this.patientTelNo = patientTelNo;
this.patientAdd = patientAdd;
this.visitDate = visitDate;
}
//set methods
public void setQueueTime(int queueTime)
{
this.queueTime = queueTime;
}
public boolean setEmergencyNo(int emergencyNo)
{
boolean varEmergencyNo = true;
if (emergencyNo != 1 && emergencyNo != 2 && emergencyNo != 3)
{
varEmergencyNo = false;
System.out.println("Emergency number is in invalid format!");
System.out.println("Emergency number is either 1, 2 or 3 only!");
System.out.println("\n");
}
else
{
this.emergencyNo = emergencyNo;
}
return varEmergencyNo;
}
public boolean setPatientName(String patientName)
{
boolean varPatientName = true;
if (patientName.equals("") || patientName.equals(null))
{
varPatientName = false;
System.out.println("The patient name cannot be empty!\n");
}
else
{
this.patientName = patientName;
}
return varPatientName;
}
public boolean setPatientIC(String patientIC)
{
boolean varPatientIC = true;
if(!patientIC.matches("^[0-9]{12}$"))
{
varPatientIC = false;
System.out.println("IC is in invalid format!");
System.out.println("It must consist of 12 numbers only!\n");
}
else
{
this.patientIC = patientIC;
}
return varPatientIC;
}
public boolean setPatientGender(String patientGender)
{
boolean varPatientGender = true;
if(!patientGender.equals("F") && !patientGender.equals("f") && !patientGender.equals("M") && !patientGender.equals("m"))
{
varPatientGender = false;
System.out.println("Gender is in invalid format!");
System.out.println("It must be either 'M' or 'F' only!\n");
}
else
{
this.patientGender = patientGender;
}
return varPatientGender;
}
public boolean setPatientTelNo(String patientTelNo)
{
boolean varPatientTelNo = true;
if((!patientTelNo.matches("^01[02346789]\\d{7}$")) && (!patientTelNo.matches("^03\\d{8}$")))
{
varPatientTelNo = false;
System.out.println("Invalid phone number!");
System.out.println("It must be in the following format : 0167890990 / 0342346789!\n");
System.out.print("\n");
}
else
{
this.patientTelNo = patientTelNo;
}
return varPatientTelNo;
}
public boolean setPatientAdd(String patientAdd)
{
boolean varPatientAdd = true;
if (patientAdd.equals("") || patientAdd.equals(null))
{
varPatientAdd = false;
System.out.println("The patient address cannot be empty!\n");
}
else
{
this.patientAdd = patientAdd;
}
return varPatientAdd;
}
public void setVisitDate(String visitDate)
{
this.visitDate = visitDate;
}
//get methods
public int getQueueTime()
{
return this.queueTime;
}
public int getEmergencyNo()
{
return this.emergencyNo;
}
public String getPatientName()
{
return this.patientName;
}
public String getPatientIC()
{
return this.patientIC;
}
public String getPatientGender()
{
return this.patientGender;
}
public String getPatientTelNo()
{
return this.patientTelNo;
}
public String getPatientAdd()
{
return this.patientAdd;
}
public String getVisitDate()
{
return this.visitDate;
}
#Override
public String toString()
{
return (this.emergencyNo + "\t\t" + this.patientName + "\t\t" + this.patientIC +
"\t\t" + this.patientGender + "\t\t" + this.patientTelNo + "\t\t" + this.patientAdd + "\t\t" + this.visitDate);
}
public String anotherToString()
{
return (this.emergencyNo + "\t\t\t\t\t\t" + this.patientName + "\t\t\t " + this.visitDate);
}
}
EmergencyCmp(Comparator)--->use for sorting the emergency numbers of the patients
import java.util.Comparator;
public class EmergencyCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
return 1;
}
else
{
return -1;
}
}
}
QueueCmp(Comparator)--->use for sorting the arrival time of the patients
import java.util.Comparator;
public class QueueCmp implements Comparator<Patient>
{
#Override
public int compare(Patient p1, Patient p2)
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
}
Main function:
import java.util.Calendar;
import java.util.Scanner;
import java.util.Arrays;
import java.util.*;
public class DSA {
public DSA() {
}
public static void main(String[] args) {
//patient's attributes
int emergencyNo;
int queueTime;
String patientName;
String patientIC;
String patientGender;
String patientTelNo;
String patientAdd;
String visitDate;
//counter
int j = 0;
int x = 0;
int y = 0;
int z = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int countEnteredPatient = 1;
int totalCount = 0;
//calendar
int nowYr, nowMn, nowDy, nowHr, nowMt, nowSc;
//others
boolean enterNewPatient = true;
String continueInput;
boolean enterNewPatient1 = true;
String continueInput1;
boolean continueEmergencyNo;
Scanner scan = new Scanner(System.in);
ListInterface<Patient> patientList = new LList<Patient>();
ListInterface<Patient> newPatientList = new LList<Patient>();
Patient[] patientArr1 = new Patient[10000];
Patient[] patientArr2 = new Patient[10000];
Patient[] patientArr3 = new Patient[10000];
Patient tempoPatient;
do{
//do-while loop for entering new patient details after viewing patient list
System.out.println("Welcome to Hospital Ten Stars!\n");
do{
//do-while loop for entering new patient details
System.out.println("Entering details of patient " + countEnteredPatient);
System.out.println("===================================\n");
Calendar calendar = Calendar.getInstance();
nowYr = calendar.get(Calendar.YEAR);
nowMn = calendar.get(Calendar.MONTH);
nowDy = calendar.get(Calendar.DAY_OF_MONTH);
nowHr = calendar.get(Calendar.HOUR);
nowMt = calendar.get(Calendar.MINUTE);
nowSc = calendar.get(Calendar.SECOND);
queueTime = calendar.get(Calendar.MILLISECOND);
visitDate = nowDy + "/" + nowMn + "/" + nowYr + ", " + nowHr + ":" + nowMt + ":" + nowSc;
//input emergency number
do{
tempoPatient = new Patient();
continueEmergencyNo = false;
int EmergencyNoOption;
try
{
do{
System.out.print("Please select 1 – Immediately life threatening, 2 – Urgent, but not immediately life threatening or 3 – Less urgent(Eg: 1) : ");
EmergencyNoOption = scan.nextInt();
scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setEmergencyNo(EmergencyNoOption) == false);
}
catch(InputMismatchException ex)
{
System.out.print("\n");
System.out.println("Invalid input detected.");
scan.nextLine();
System.out.print("\n");
continueEmergencyNo = true;
}
}while(continueEmergencyNo);
//input patient name
do{
System.out.print("Patient name(Eg: Christine Redfield) : ");
patientName = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientName(patientName) == false);
//input patient ic no
do{
System.out.print("Patient IC number(Eg: 931231124567) : ");
patientIC = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientIC(patientIC) == false);
//input patient gender
do{
System.out.print("Patient gender(Eg: M) : ");
patientGender = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientGender(patientGender) == false);
//input patient tel. no
do{
System.out.print("Patient tel.No(without'-')(Eg: 0162345678/0342980123) : ");
patientTelNo = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientTelNo(patientTelNo) == false);
//input patient address
do{
System.out.print("Patient address(Eg: 4-C9 Jln Besar 123, Taman Besar, 56000 Kuala Lumpur) : ");
patientAdd = scan.nextLine();
System.out.print("\n");
}while(tempoPatient.setPatientAdd(patientAdd) == false);
tempoPatient.setQueueTime(queueTime);
tempoPatient.setVisitDate(visitDate);
patientList.add(tempoPatient);
//decide whether want to enter a new patient or not
do{
System.out.print("Do you want to enter another new patient?(Eg: Y/N) : ");
continueInput = scan.nextLine();
if(continueInput.equals("Y") || continueInput.equals("y"))
{
enterNewPatient = true;
System.out.print("\n");
}
else if(continueInput.equals("N") || continueInput.equals("n"))
{
enterNewPatient = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput.equals("Y") && !continueInput.equals("y") && !continueInput.equals("N") && !continueInput.equals("n"));
countEnteredPatient++;
}while(enterNewPatient); //end do-while loop for entering new patient details
System.out.println("\nWaiting list of patient will be displayed soon.\n");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
System.out.println("Waiting list of patients");
System.out.println("========================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= patientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + patientList.getEntry(i).anotherToString());
}
do{
System.out.print("\nSo, now do you want to enter another new patient?(Eg: Y/N) : ");
continueInput1 = scan.nextLine();
if(continueInput1.equals("Y") || continueInput1.equals("y"))
{
enterNewPatient1 = true;
System.out.print("\n");
}
else if(continueInput1.equals("N") || continueInput1.equals("n"))
{
enterNewPatient1 = false;
}
else
{
System.out.println("\n");
System.out.println("Please enter Y/N only.\n");
}
}while(!continueInput1.equals("Y") && !continueInput1.equals("y") && !continueInput1.equals("N") && !continueInput1.equals("n"));
}while(enterNewPatient1);//end do-while loop for entering new patient details after viewing patient list
System.out.println("\nNow rearranging the list based on the seriouness and their arrival time.");
try{
Thread.sleep(1000);
}
catch (Exception e)
{
}
//create an unsorted array
Patient[] tempoPatientArr = new Patient[patientList.getLength()];
//copy the contents of patientList into tempoPatientArr
for(int i = 1; i <= patientList.getLength(); i++ )
{
tempoPatientArr[i-1] = patientList.getEntry(i);
}
//sort tempoPatientArr
Arrays.sort(tempoPatientArr, new EmergencyCmp());
//the above part until this comment line does not have problem
//check the emergency no and then categorise accordingly
for(int i = 0; i < tempoPatientArr.length; i++)
{
if(tempoPatientArr[i].getEmergencyNo() == 1)
{
patientArr1[x] = tempoPatientArr[i];
x++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 2)
{
patientArr2[y] = tempoPatientArr[i];
y++;
}
else if(tempoPatientArr[i].getEmergencyNo() == 3)
{
patientArr3[z] = tempoPatientArr[i];
z++;
}
}
//to check how many !null elements by using count for 3 sub-arrays
for(int i = 0; i < patientArr1.length; i++)
{
if(patientArr1[i] != null)
{
count1++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr2.length; i++)
{
if(patientArr2[i] != null)
{
count2++;
}
else
{
break;
}
}
for(int i = 0; i < patientArr3.length; i++)
{
if(patientArr3[i] != null)
{
count3++;
}
else
{
break;
}
}
//new array with elimination of null values
Patient[] newPatientArr1 = new Patient[count1];
Patient[] newPatientArr2 = new Patient[count2];
Patient[] newPatientArr3 = new Patient[count3];
//copy the contents of old sub arrays(the arrays with null values) into the new sub arrays(without null values)
for(int i = 0; i < newPatientArr1.length; i++)
{
newPatientArr1[i] = patientArr1[i];
}
for(int i = 0; i < newPatientArr2.length; i++)
{
newPatientArr2[i] = patientArr2[i];
}
for(int i = 0; i < newPatientArr3.length; i++)
{
newPatientArr3[i] = patientArr3[i];
}
totalCount = count1 + count2 + count3;
//array that used to combine all the sub-arrays
Patient[] newPatientArr = new Patient[totalCount];
//sort all sub new arrays
Arrays.sort(newPatientArr1, new QueueCmp());
Arrays.sort(newPatientArr2, new QueueCmp());
Arrays.sort(newPatientArr3, new QueueCmp());
//combine the contents of sub new arrays into the newPatientArr array
do{
for (int i = 0; i < count1; i++)
{
newPatientArr[j] = newPatientArr1[i];
j++;
}
for (int b = 0; b < count2; b++)
{
newPatientArr[j] = newPatientArr2[b];
j++;
}
for (int c = 0; c < count3; c++)
{
newPatientArr[j] = newPatientArr3[c];
j++;
}
}while(j < totalCount);
//relink the nodes
for(int i = 0; i < newPatientArr.length; i++)
{
newPatientList.add(newPatientArr[i]);
}
System.out.println("\nSorted waiting list of patients");
System.out.println("===============================\n");
System.out.println("Number\t\tEmergency number\t\tPatient name\t\t ArrivalTime");
System.out.println("============================================================================");
for(int i = 1; i <= newPatientList.getLength(); i++)
{
System.out.println(i + "\t\t\t" + newPatientList.getEntry(i).anotherToString());
}
}
}
Interface and LList class definitely do not have problems. So everyone can skip the 2 parts.
For the main function, I have a comment like this:
//the above part until this comment line does not have problem
When you all see the comment, that means the previous code does not have problem and you all may skip it and below is an attachment of the result that I got earlier:
So, from the picture you all can see that the sorting of arrival time is not correct. I hope that I can know why does this problem occurs since I cannot figure it out by myself. Thanks to all of you first.
So, after taking the advice of #Scott Hunter, I have made the following modification to the EmergencyCmp:
#Override
public int compare(Patient p1, Patient p2)
{
int value = 0;
if(p1.getEmergencyNo() > p2.getEmergencyNo())
{
value = 1;
}
else if(p1.getEmergencyNo() < p2.getEmergencyNo())
{
value = -1;
}
else if(p1.getEmergencyNo() == p2.getEmergencyNo())
{
if(p1.getQueueTime() > p2.getQueueTime())
{
return 1;
}
else
{
return -1;
}
}
return value;
}
However, the time sorting still produce a wrong result.
As I understand it (which I may not; you provided a LOT of extraneous stuff), it looks like you are trying to perform 2 distinct sorts, one after the other, such that the second is undoing the work of the first. Instead, you should define a single Comparator which compares emergency numbers and, only if they are the same, compares arrival times.