binary Tree: printing the data in ascending order - java

I am a beginner in java .. I have just started the data structure online.
I want to print the values i have added to the binary tree in ascending order.
I have created a method print and tried it with these values:
9,5,2,8,3
It printed this output and stopped
2 , 3 ,8
the Nodes have to constructors :
Constructor 1
public Node(int value){
this.Value=value;
isEmpty=false;
this.left=new Node();
this.right=new Node();
}
Constructor 2
public Node(){
isEmpty=true;
}
The Adding method :
public void add(int value) {
if (Objects.isNull(root)) {
root = new Node(value);
root.isEmpty = false;
}
Node current = root;
while (true) {
if (value < current.Value) {
if (current.left.isEmpty) {
current.left.prev = current;
current = current.left;
current.Value = value;
current.isEmpty = false;
current.left = new Node();
current.right = new Node();
break;
} else {
current = current.left;
}
} else {
if (current.right.isEmpty) {
current.right.prev = current;
current = current.right;
current.Value = value;
current.isEmpty = false;
current.left = new Node();
current.right = new Node();
break;
} else {
current = current.right;
}
}
}
}
The Print method
ArrayList<Node> list = new ArrayList();
Node current = root;while(true){
if(!current.left.isEmpty ){
if(!list.contains(current.left)){
current=current.left;
continue;
}
} else {
System.out.println(current.Value);
list.add(current);
if(!current.right.isEmpty && !list.contains(current.right)){
current=current.right;
continue;
}
current=current.prev.prev;
}

To print data from BST you need to do inorder traversal. In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order. To get nodes of BST in non-increasing order, a variation of Inorder traversal where Inorder traversal s reversed can be used.
Algorithm Inorder(tree)
1. Traverse the left subtree, i.e., call Inorder(left-subtree)
2. Visit the root.
3. Traverse the right subtree, i.e., call Inorder(right-subtree)
/* Given a binary tree, print its nodes in inorder*/
void printInorder(Node node)
{
if (node == null)
return;
/* first recur on left child */
printInorder(node.left);
/* then print the data of node */
if(!node.isEmpty){
System.out.print(node.value+ " ");
}
/* now recur on right child */
printInorder(node.right);
}
Time Complexity: O(n)
If the tree is not BST. You can create List and write the tree's values into the list and sort the list in ascending order.
List<Integer> treeValues = new ArrayList<Integer>();
List<Integer> treeToList(Node node){
if (node == null)
return;
printInorder(node.left);
if(!node.isEmpty){
treeValues.add(node.value);
}
printInorder(node.right);
}
void sortedTree(Node node){
List<Integer> treeData = treeToList(node);
Collections.sort(treeData);
for(int i=0; i<treeData.size();i++ ){
System.out.println(treeData.get(i));
}
}

Related

Java - Return the node visited after node x in a pre-order traversal of BT

I am being asked to "Return the node visited after node x in a pre-order traversal of a binary tree" in Java for school. I have created a code to list all the nodes in pre-order, but I'm not sure how to print off a single node.
My first class to create the nodes is:
public class TreeNode {
int value; // The data in this node.
TreeNode left; // Pointer to the left subtree.
TreeNode right; // Pointer to the right subtree.
TreeNode parent; //Pointer to the parent of the node.
TreeNode(int value) {
this.value = value;
this.right = null;
this.left = null;
this.parent = null;
}
public void displayNode() { //Displays the value of the node.
System.out.println(value + " ");
}
I then have the class to build the binary tree. It also prints the whole tree in pre-order:
public class BTree2 {
TreeNode root; // the first node in the tree
public boolean isEmpty() // true if no links
{
return root == null;
}
private TreeNode addRecursive(TreeNode current, int value) {
if (current == null) {
return new TreeNode(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
public void add(int value) {
root = addRecursive(root, value);
}
void printPreorder(TreeNode node) {
if (node == null) {
return;
}
System.out.print(node.value + " "); /* first print data of node */
printPreorder(node.left); /* then recur on left subtree */
printPreorder(node.right); /* now recur on right subtree */
}
void printPreorder() {
printPreorder(root);
}
This is where I get stuck: how do I print off the node that comes after a particular node, and not just the whole tree? I thought it would be:
public TreeNode findPreorder(int key) // find node with given key
{ // (assumes non-empty tree)
TreeNode current = root; // start at root
while (current.value == key) // while there is a match
{
current = current.left;
if (key < current.value) // go left?
{
current = current.right;
} else {
current = current.right; // or go right?
}
if (current == null) // if no child,
{
return null; // didn't find it
}
}
return current; // found it
}
But that's not working. This is my test code in my main:
public static void main(String[] args) {
BTree2 tree = new BTree2();
tree.root = new TreeNode(1);
tree.root.left = new TreeNode(2);
tree.root.right = new TreeNode(3);
tree.root.left.left = new TreeNode(4);
tree.root.left.right = new TreeNode(5);
System.out.println("Preorder traversal of binary tree is ");
tree.printPreorder();
System.out.println("the node after 1 is " + tree.findPreorder(1).value);
}
My output is:
Preorder traversal of binary tree is
1 2 4 5 3
the node after 1 is 5
Any ideas? Thanks!!
You can basically use the same function for visiting in pre order manner with some modifications:
void findNextInPreOrder(TreeNode node, int key) {
if (node == null) {
return;
}
if (node.value == key) {
if(node.left != null){
System.out.print("Next is on left: " + node.left.value);
} else if (node.right != null){
System.out.print("Next is on right: " + node.right.value);
} else {
System.out.print("There is no next node.");
}
}
findNextInPreOrder(node.left); /* then recur on left subtree */
findNextInPreOrder(node.right); /* now recur on right subtree */
}
Thank you!! I also added an 'else' statement since that seemed to help me a bit with the implementation:
void findNextInPreOrder(Node node, int key) {
if (node == null) {
return;
}
if (node.value == key) {
if (node.left != null) {
System.out.print("Next is on left: " + node.left.value);
} else if (node.right != null) {
System.out.print("Next is on right: " + node.right.value);
} else {
System.out.print("There is no next node.");
}
} else {
findNextInPreOrder(node.left, key);
/* then recur on left subtree */
findNextInPreOrder(node.right, key);
/* now recur on right subtree */
}
}

how to print a tree in order by using stack and depth first search?

import java.util.LinkedList;
import java.util.Queue;
class Node {
public int iData; // data item (key)
public double dData; // data item
public Node leftChild; // this node's left child
public Node rightChild; // this node's right child
public int level;
public boolean flag;
public void displayNode() // display ourself
{
System.out.print('{');
System.out.print(level);
System.out.print(", ");
System.out.print(iData);
System.out.print(", ");
System.out.print(dData);
System.out.print("} ");
System.out.println(" ");
}
} // end class Node
// //////////////////////////////////////////////////////////////
class Tree {
private Node root; // first node of tree
// -------------------------------------------------------------
public Tree() // constructor
{
root = null;
} // no nodes in tree yet
// -------------------------------------------------------------
public void insert(int id, double dd) {
Node newNode = new Node(); // make new node
newNode.iData = id; // insert data
newNode.dData = dd;
if (root == null) // no node in root
root = newNode;
else // root occupied
{
Node current = root; // start at root
Node parent;
while (true) // (exits internally)
{
parent = current;
if (id < current.iData) // go left?
{
current = current.leftChild;
if (current == null) // if end of the line,
{ // insert on left
parent.leftChild = newNode;
return;
}
} // end if go left
else // or go right?
{
current = current.rightChild;
if (current == null) // if end of the line
{ // insert on right
parent.rightChild = newNode;
return;
}
} // end else go right
} // end while
} // end else not root
} // end insert()
// -------------------------------------------------------------
public void breadthFirstDisplay() {
Queue newQueue = new LinkedList();
int level = 0;
newQueue.add(root);
int temp = root.iData;
while (!newQueue.isEmpty()) {
Node theNode = (Node) newQueue.remove();
if (temp > theNode.iData)
level++;
theNode.level = level;
theNode.displayNode();
temp = theNode.iData;
if (theNode.leftChild != null) {
newQueue.add(theNode.leftChild);
}
if (theNode.rightChild != null) {
newQueue.add(theNode.rightChild);
}
}
}
public void depthFirstStackDisplay() {
}
// -------------------------------------------------------------
} // end class Tree
// //////////////////////////////////////////////////////////////
class TreeApp {
public static void main(String[] args){
Tree theTree = new Tree();
theTree.insert(5, 1.5);
theTree.insert(4, 1.2);
theTree.insert(6, 1.7);
theTree.insert(9, 1.5);
theTree.insert(1, 1.2);
theTree.insert(2, 1.7);
theTree.insert(3, 1.5);
theTree.insert(7, 1.2);
theTree.insert(8, 1.7);
theTree.breadthFirstDisplay();
theTree.depthFirstStackDisplay();
}// -------------------------------------------------------------
} // end class TreeApp
// //////////////////////////////////////////////////////////////
I want to write a function by depth first search
so that the output is 1,2,3,4,5,6,7,8,9
Boolean flag is set in class Node and the i want that the function is similar to breadth first search.
I can't find relevant source to help me to complete it.
you can try this alogo to print depth first traversal (inorder traversal according to your problem ).It will use stack.
1) Create an empty stack S.
2) Initialize current node as root
3) Push the current node to S and set current = current->left until current is NULL
4) If current is NULL and stack is not empty then
a) Pop the top item from stack.
b) Print the popped item, set current = popped_item->right
c) Go to step 3.
5) If current is NULL and stack is empty then we are done.
I don't know much about java but you can take the help of this c code :
/* Iterative function for inorder tree traversal */
void inOrder(struct Node *root)
{
/* set current to root of binary tree */
struct Node *current = root;
struct sNode *s = NULL; /* Initialize stack s */
bool done = 0;
while (!done)
{
/* Reach the left most Node of the current Node */
if(current != NULL)
{
/* place pointer to a tree node on the stack before traversing
the node's left subtree */
push(&s, current);
current = current->leftChild;
}
/* backtrack from the empty subtree and visit the Node
at the top of the stack; however, if the stack is empty,
you are done */
else
{
if (!isEmpty(s))
{
current = pop(&s);
printf("%d ", current->idata);
/* we have visited the node and its left subtree.
Now, it's right subtree's turn */
current = current->rightChild;
}
else
done = 1;
}
} /* end of while */
}

Converting an ordered binary tree to a doubly circular link list

I have a ordered binary tree:
4
|
|-------|
2 5
|
|-------|
1 3
The leaves point to null. I have to create a doubly link list which should look like
1<->2<->3<->4<->5
(Obviously 5 should point to 1)
The node class is as follows:
class Node {
Node left;
Node right;
int value;
public Node(int value)
{
this.value = value;
left = null;
right = null;
}
}
As you can see the doubly link list is ordered (sorted) as well.
Question: I have to create the linked list form the tree without using any extra pointers. The left pointer of the tree should be the previous pointer of the list and the right pointer of the tree should be the next pointer of the list.
What I thought off: Since the tree is an ordered tree, the inorder traversal would give me a sorted list. But while doing the inorder traversal I am not able to see, where and how to move the pointers to form a doubly linked list.
P.S I checked some variations of this question but none of them gave me any clues.
It sounds like you need a method that accepts a Node reference to the root of the tree and returns a Node reference to the head of a circular list, where no new Node objects are created. I would approach this recursively, starting with the simple tree:
2
|
|-----|
1 3
You don't say whether the tree is guaranteed to be full, so we need to allow for 1 and/or 3 being null. The following method should work for this simple tree:
Node simpleTreeToList(Node root) {
if (root == null) {
return null;
}
Node left = root.left;
Node right = root.right;
Node head;
if (left == null) {
head = root;
} else {
head = left;
left.right = root;
// root.left is already correct
}
if (right == null) {
head.left = root;
root.right = head;
} else {
head.left = right;
right.right = head;
right.left = root;
}
return head;
}
Once it is clear how this works, it isn't too hard to generalize it to a recursive method that works for any tree. It is a very similar method:
Node treeToList(Node root) {
if (root == null) {
return null;
}
Node leftTree = treeToList(root.left);
Node rightTree = treeToList(root.right);
Node head;
if (leftTree == null) {
head = root;
} else {
head = leftTree;
leftTree.left.right = root;
root.left = leftTree.left;
}
if (rightTree == null) {
head.left = root;
root.right = head;
} else {
head.left = rightTree.left;
rightTree.left.right = head;
rightTree.left = root;
root.right = rightTree;
}
return head;
}
If I got all the link assignments covered correctly, this should be all you need.
Do an in-order traversal of the list, adding each list item to the doubly linked list as you encounter it. When done, add an explicit link between the first and last items.
Update 3/6/2012: Since you must reuse the Node objects you already have, after you put the node objects into the the list, you can then iterate over the list and reset the left and right pointers of the Node objects to point to their siblings. Once that is done, you can get rid of the list and simply return the first node object.
This should also work:
NodeLL first = null;
NodeLL last = null;
private void convertToLL(NodeBST root) {
if (root == null) {
return;
}
NodeLL newNode = new NodeLL(root.data);
convertToLL(root.left);
final NodeLL l = last;
last = newNode;
if (l == null)
first = newNode;
else {
l.next = newNode;
last.prev = l;
}
convertToLL(root.right);
}
Let your recursion return the left and right end of formed list. Then you link your current node to the last of the left list, and first of the right list. Basic case it, when there is no left or right element, which is the node it self for both. Once all is done, you can link the first and last of the final result. Below is the java code.
static void convertToSortedList(TreeNode T){
TreeNode[] r = convertToSortedListHelper(T);
r[1].next = r[0];
r[0].prev= r[1];
}
static TreeNode[] convertToSortedListHelper(TreeNode T){
TreeNode[] ret = new TreeNode[2];
if (T == null) return ret;
if (T.left == null && T.right == null){
ret[0] = T;
ret[1] = T;
return ret;
}
TreeNode[] left = TreeNode.convertToSortedListHelper(T.left);
TreeNode[] right = TreeNode.convertToSortedListHelper(T.right);
if (left[1] != null) left[1].next = T;
T.prev = left[1];
T.next = right[0];
if (right[0] != null) right[0].prev = T;
ret[0] = left[0]==null? T:left[0];
ret[1] = right[1]==null? T:right[1];
return ret;
}
Add the following method to your Node class
public Node toLinked() {
Node leftmost = this, rightmost = this;
if (right != null) {
right = right.toLinked();
rightmost = right.left;
right.left = this;
}
if (left != null) {
leftmost = left.toLinked();
left = leftmost.left;
left.right = this;
}
leftmost.left = rightmost;
rightmost.right = leftmost;
return leftmost;
}
EDIT By maintaining the invariant that the list returned by toLinked() has the proper form, you can easily get the left- and rightmost nodes in the sublist returned by the recursive call on the subtrees
/* input: root of BST. Output: first node of a doubly linked sorted circular list. **Constraints**: do it in-place. */
public static Node transform(Node root){
if(root == null){
return null;
}
if(root.isLeaf()){
root.setRight(root);
root.setLeft(root);
return root;
}
Node firstLeft = transform(root.getLeft());
Node firstRight = transform(root.getRight());
Node lastLeft = firstLeft == null ? null : firstLeft.getLeft();
Node lastRight= firstRight == null ? null : firstRight.getLeft();
if(firstLeft != null){
lastLeft.setRight(root);
root.setLeft(lastLeft);
if(lastRight == null){
firstLeft.setLeft(root);
}
else{
firstLeft.setLeft(lastRight);
root.setRight(firstRight);
}
}
if(firstRight != null){
root.setRight(firstRight);
firstRight.setLeft(root);
if(lastLeft == null){
root.setLeft(lastRight);
lastRight.setLeft(root);
firstLeft = root;
}
else{
root.setLeft(lastLeft);
lastRight.setRight(firstLeft);
}
}
return firstLeft;
}

How do implement a breadth first traversal?

This is what I have. I thought pre-order was the same and mixed it up with depth first!
import java.util.LinkedList;
import java.util.Queue;
public class Exercise25_1 {
public static void main(String[] args) {
BinaryTree tree = new BinaryTree(new Integer[] {10, 5, 15, 12, 4, 8 });
System.out.print("\nInorder: ");
tree.inorder();
System.out.print("\nPreorder: ");
tree.preorder();
System.out.print("\nPostorder: ");
tree.postorder();
//call the breadth method to test it
System.out.print("\nBreadthFirst:");
tree.breadth();
}
}
class BinaryTree {
private TreeNode root;
/** Create a default binary tree */
public BinaryTree() {
}
/** Create a binary tree from an array of objects */
public BinaryTree(Object[] objects) {
for (int i = 0; i < objects.length; i++) {
insert(objects[i]);
}
}
/** Search element o in this binary tree */
public boolean search(Object o) {
return search(o, root);
}
public boolean search(Object o, TreeNode root) {
if (root == null) {
return false;
}
if (root.element.equals(o)) {
return true;
}
else {
return search(o, root.left) || search(o, root.right);
}
}
/** Return the number of nodes in this binary tree */
public int size() {
return size(root);
}
public int size(TreeNode root) {
if (root == null) {
return 0;
}
else {
return 1 + size(root.left) + size(root.right);
}
}
/** Return the depth of this binary tree. Depth is the
* number of the nodes in the longest path of the tree */
public int depth() {
return depth(root);
}
public int depth(TreeNode root) {
if (root == null) {
return 0;
}
else {
return 1 + Math.max(depth(root.left), depth(root.right));
}
}
/** Insert element o into the binary tree
* Return true if the element is inserted successfully */
public boolean insert(Object o) {
if (root == null) {
root = new TreeNode(o); // Create a new root
}
else {
// Locate the parent node
TreeNode parent = null;
TreeNode current = root;
while (current != null) {
if (((Comparable)o).compareTo(current.element) < 0) {
parent = current;
current = current.left;
}
else if (((Comparable)o).compareTo(current.element) > 0) {
parent = current;
current = current.right;
}
else {
return false; // Duplicate node not inserted
}
}
// Create the new node and attach it to the parent node
if (((Comparable)o).compareTo(parent.element) < 0) {
parent.left = new TreeNode(o);
}
else {
parent.right = new TreeNode(o);
}
}
return true; // Element inserted
}
public void breadth() {
breadth(root);
}
// Implement this method to produce a breadth first
// search traversal
public void breadth(TreeNode root){
if (root == null)
return;
System.out.print(root.element + " ");
breadth(root.left);
breadth(root.right);
}
/** Inorder traversal */
public void inorder() {
inorder(root);
}
/** Inorder traversal from a subtree */
private void inorder(TreeNode root) {
if (root == null) {
return;
}
inorder(root.left);
System.out.print(root.element + " ");
inorder(root.right);
}
/** Postorder traversal */
public void postorder() {
postorder(root);
}
/** Postorder traversal from a subtree */
private void postorder(TreeNode root) {
if (root == null) {
return;
}
postorder(root.left);
postorder(root.right);
System.out.print(root.element + " ");
}
/** Preorder traversal */
public void preorder() {
preorder(root);
}
/** Preorder traversal from a subtree */
private void preorder(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.element + " ");
preorder(root.left);
preorder(root.right);
}
/** Inner class tree node */
private class TreeNode {
Object element;
TreeNode left;
TreeNode right;
public TreeNode(Object o) {
element = o;
}
}
}
Breadth first search
Queue<TreeNode> queue = new LinkedList<BinaryTree.TreeNode>() ;
public void breadth(TreeNode root) {
if (root == null)
return;
queue.clear();
queue.add(root);
while(!queue.isEmpty()){
TreeNode node = queue.remove();
System.out.print(node.element + " ");
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
}
Breadth first is a queue, depth first is a stack.
For breadth first, add all children to the queue, then pull the head and do a breadth first search on it, using the same queue.
For depth first, add all children to the stack, then pop and do a depth first on that node, using the same stack.
It doesn't seem like you're asking for an implementation, so I'll try to explain the process.
Use a Queue. Add the root node to the Queue. Have a loop run until the queue is empty. Inside the loop dequeue the first element and print it out. Then add all its children to the back of the queue (usually going from left to right).
When the queue is empty every element should have been printed out.
Also, there is a good explanation of breadth first search on wikipedia: http://en.wikipedia.org/wiki/Breadth-first_search
public void breadthFirstSearch(Node root, Consumer<String> c) {
List<Node> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
Node n = queue.remove(0);
c.accept(n.value);
if (n.left != null)
queue.add(n.left);
if (n.right != null)
queue.add(n.right);
}
}
And the Node:
public static class Node {
String value;
Node left;
Node right;
public Node(final String value, final Node left, final Node right) {
this.value = value;
this.left = left;
this.right = right;
}
}
//traverse
public void traverse()
{
if(node == null)
System.out.println("Empty tree");
else
{
Queue<Node> q= new LinkedList<Node>();
q.add(node);
while(q.peek() != null)
{
Node temp = q.remove();
System.out.println(temp.getData());
if(temp.left != null)
q.add(temp.left);
if(temp.right != null)
q.add(temp.right);
}
}
}
}
This code which you have written, is not producing correct BFS traversal:
(This is the code you claimed is BFS, but in fact this is DFS!)
// search traversal
public void breadth(TreeNode root){
if (root == null)
return;
System.out.print(root.element + " ");
breadth(root.left);
breadth(root.right);
}
For implementing the breadth first search, you should use a queue. You should push the children of a node to the queue (left then right) and then visit the node (print data). Then, yo should remove the node from the queue. You should continue this process till the queue becomes empty. You can see my implementation of the BFS here: https://github.com/m-vahidalizadeh/foundations/blob/master/src/algorithms/TreeTraverse.java
Use the following algorithm to traverse in breadth first search-
First add the root node into the queue with the put method.
Iterate while the queue is not empty.
Get the first node in the queue, and then print its value.
Add both left and right children into the queue (if the current
nodehas children).
Done. We will print the value of each node, level by level,by
poping/removing the element
Code is written below-
Queue<TreeNode> queue= new LinkedList<>();
private void breadthWiseTraversal(TreeNode root) {
if(root==null){
return;
}
TreeNode temp = root;
queue.clear();
((LinkedList<TreeNode>) queue).add(temp);
while(!queue.isEmpty()){
TreeNode ref= queue.remove();
System.out.print(ref.data+" ");
if(ref.left!=null) {
((LinkedList<TreeNode>) queue).add(ref.left);
}
if(ref.right!=null) {
((LinkedList<TreeNode>) queue).add(ref.right);
}
}
}
The following is a simple BFS implementation for BinaryTree with java 8 syntax.
void bfsTraverse(Node node, Queue<Node> tq) {
if (node == null) {
return;
}
System.out.print(" " + node.value);
Optional.ofNullable(node.left).ifPresent(tq::add);
Optional.ofNullable(node.right).ifPresent(tq::add);
bfsTraverse(tq.poll(), tq);
}
Then invoke this with root node and a Java Queue implementation
bfsTraverse(root, new LinkedList<>());
Even better if it is regular tree, could use following line instead as there is not only left and right nodes.
Optional.ofNullable(node.getChildern()).ifPresent(tq::addAll);
public static boolean BFS(ListNode n, int x){
if(n==null){
return false;
}
Queue<ListNode<Integer>> q = new Queue<ListNode<Integer>>();
ListNode<Integer> tmp = new ListNode<Integer>();
q.enqueue(n);
tmp = q.dequeue();
if(tmp.val == x){
return true;
}
while(tmp != null){
for(ListNode<Integer> child: n.getChildren()){
if(child.val == x){
return true;
}
q.enqueue(child);
}
tmp = q.dequeue();
}
return false;
}

Manually sorting a linked list in Java (lexically)

I am implementing my own linked list in Java. The node class merely has a string field called "name" and a node called "link". Right now I have a test driver class that only inserts several names sequentially. Now, I am trying to write a sorting method to order the nodes alphabetically, but am having a bit of trouble with it. I found this pseudocode of a bubblesort from someone else's post and tried to implement it, but it doesn't fully sort the entries. I'm not really quite sure why. Any suggestions are appreciated!
private void sort()
{
//Enter loop only if there are elements in list
boolean swapped = (head != null);
// Only continue loop if a swap is made
while (swapped)
{
swapped = false;
// Maintain pointers
Node curr = head;
Node next = curr.link;
Node prev = null;
// Cannot swap last element with its next
while (next != null)
{
// swap if items in wrong order
if (curr.name.compareTo(next.name) < 0)
{
// notify loop to do one more pass
swapped = true;
// swap elements (swapping head in special case
if (curr == head)
{
head = next;
Node temp = next.link;
next.link = curr;
curr.link = temp;
curr = head;
}
else
{
prev.link = curr.link;
curr.link = next.link;
next.link = curr;
curr = next;
}
}
// move to next element
prev = curr;
curr = curr.link;
next = curr.link;
}
}
}
I spent some minutes eyeballing your code for errors but found none.
I'd say until someone smarter or more hard working comes along you should try debugging this on your own. If you have an IDE like Eclipse you can single-step through the code while watching the variables' values; if not, you can insert print statements in a few places and hand-check what you see with what you expected.
UPDATE I
I copied your code and tested it. Apart from the fact that it sorts in descending order (which may not be what you intended) it worked perfectly for a sample of 0, 1 and 10 random nodes. So where's the problem?
UPDATE II
Still guessing what could be meant by "it doesn't fully sort the entries." It's possible that you're expecting lexicographic sorting (i.e. 'a' before 'B'), and that's not coming out as planned for words with mixed upper/lower case. The solution in this case is to use the String method compareToIgnoreCase(String str).
This may not be the solution you're looking for, but it's nice and simple. Maybe you're lazy like I am.
Since your nodes contain only a single item of data, you don't really need to re-shuffle your nodes; you could simply exchange the values on the nodes while leaving the list's structure itself undisturbed.
That way, you're free to implement Bubble Sort quite simply.
you should use the sorting procedures supplied by the language.
try this tutorial.
Basically, you need your element class to implement java.lang.Comparable, in which you will just delegate to obj.name.compareTo(other.name)
you can then use Collections.sort(yourCollection)
alternatively you can create a java.util.Comparator that knows how to compare your objects
To obtain good performance you can use Merge Sort.
Its time complexity is O(n*log(n)) and can be implemented without memory overhead for lists.
Bubble sort is not good sorting approach. You can read the What is a bubble sort good for? for details.
This may be a little too late. I would build the list by inserting everything in order to begin with because sorting a linked list is not fun.
I'm positive your teacher or professor doesn't want you using java's native library. However that being said, there is no real fast way to resort this list.
You could read all the nodes in the order that they are in and store them into an array. Sort the array and then relink the nodes back up. I think the Big-Oh complexity of this would be O(n^2) so in reality a bubble sort with a linked list is sufficient
I have done merge sort on the singly linked list and below is the code.
public class SortLinkedList {
public static Node sortLinkedList(Node node) {
if (node == null || node.next == null) {
return node;
}
Node fast = node;
Node mid = node;
Node midPrev = node;
while (fast != null && fast.next != null) {
fast = fast.next.next;
midPrev = mid;
mid = mid.next;
}
midPrev.next = null;
Node node1 = sortLinkedList(node);
Node node2 = sortLinkedList(mid);
Node result = mergeTwoSortedLinkedLists(node1, node2);
return result;
}
public static Node mergeTwoSortedLinkedLists(Node node1, Node node2) {
if (null == node1 && node2 != null) {
return node2;
} else if (null == node2 && node1 != null) {
return node1;
} else if (null == node1 && null == node2) {
return null;
} else {
Node result = node1.data <= node2.data ? node1 : node2;
Node prev1 = null;
while (node1 != null && node2 != null) {
if (node1.data <= node2.data) {
prev1 = node1;
node1 = node1.next;
} else {
Node next2 = node2.next;
node2.next = node1;
if (prev1 != null) {
prev1.next = node2;
}
node1 = node2;
node2 = next2;
}
}
if (node1 == null && node2 != null) {
prev1.next = node2;
}
return result;
}
}
public static void traverseNode(Node node) {
while (node != null) {
System.out.print(node + " ");
node = node.next;
}
System.out.println();
}
public static void main(String[] args) {
MyLinkedList ll1 = new MyLinkedList();
ll1.insertAtEnd(10);
ll1.insertAtEnd(2);
ll1.insertAtEnd(20);
ll1.insertAtEnd(4);
ll1.insertAtEnd(9);
ll1.insertAtEnd(7);
ll1.insertAtEnd(15);
ll1.insertAtEnd(-3);
System.out.print("list: ");
ll1.traverse();
System.out.println();
traverseNode(sortLinkedList(ll1.start));
}
}
The Node class:
public class Node {
int data;
Node next;
public Node() {
data = 0;
next = null;
}
public Node(int data) {
this.data = data;
}
public int getData() {
return this.data;
}
public Node getNext() {
return this.next;
}
public void setData(int data) {
this.data = data;
}
public void setNext(Node next) {
this.next = next;
}
#Override
public String toString() {
return "[ " + data + " ]";
}
}
The MyLinkedList class:
public class MyLinkedList {
Node start;
public void insertAtEnd(int data) {
Node newNode = new Node(data);
if (start == null) {
start = newNode;
return;
}
Node traverse = start;
while (traverse.getNext() != null) {
traverse = traverse.getNext();
}
traverse.setNext(newNode);
}
public void traverse() {
if (start == null)
System.out.println("List is empty");
else {
Node tempNode = start;
do {
System.out.print(tempNode.getData() + " ");
tempNode = tempNode.getNext();
} while (tempNode != null);
System.out.println();
}
}
}

Categories