Data Structures
Linked List Advantages/Disadvantages
Advantages over arrays 1) Dynamic size 2) Ease of insertion/deletion Drawbacks: 1) Random access is not allowed. We have to access elements sequentially starting from the first node. So we cannot do binary search with linked lists. 2) Extra memory space for a pointer is required with each element of the list.
Array
An array is collection of items stored at continuous memory locations. The idea is to store multiple items of same type together. This makes it easier to calculate the position of each element by simply adding an offset to a base value, i.e., the memory location of the first element of the array (generally denoted by the name of the array).
Singly Linked List
Like arrays, Linked List is a linear data structure. Unlike arrays, linked list elements are not stored at contiguous location; the elements are linked using pointers.
Iterative Tower of Hanoi
Tower of Hanoi is a mathematical puzzle. It consists of three poles and a number of disks of different sizes which can slide onto any poles. The puzzle starts with the disk in a neat stack in ascending order of size in one pole, the smallest at the top thus making a conical shape. The objective of the puzzle is to move all the disks from one pole (say 'source pole') to another pole (say 'destination pole') with the help of third pole (say auxiliary pole). The puzzle has the following two rules: 1. You can't place a larger disk onto smaller disk 2. Only one disk can be moved at a time Iterative Algorithm: 1. Calculate the total number of moves required i.e. "pow(2, n) - 1" here n is number of disks. 2. If number of disks (i.e. n) is even then interchange destination pole and auxiliary pole. 3. for i = 1 to total number of moves: if i%3 == 1: legal movement of top disk between source pole and destination pole if i%3 == 2: legal movement top disk between source pole and auxiliary pole if i%3 == 0: legal movement top disk between auxiliary pole and destination pole // Java program for iterative // Tower of Hanoi public class TOH { // A structure to represent a stack class Stack { int capacity; int top; int array[]; } // function to create a stack of given capacity. Stack createStack(int capacity) { Stack stack=new Stack(); stack.capacity = capacity; stack.top = -1; stack.array = new int[capacity]; return stack; } // Stack is full when top is equal to the last index boolean isFull(Stack stack) { return (stack.top == stack.capacity - 1); } // Stack is empty when top is equal to -1 boolean isEmpty(Stack stack) { return (stack.top == -1); } // Function to add an item to stack. It increases // top by 1 void push(Stack stack,int item) { if(isFull(stack)) return; stack.array[++stack.top] = item; } // Function to remove an item from stack. It // decreases top by 1 int pop(Stack stack) { if(isEmpty(stack)) return Integer.MIN_VALUE; return stack.array[stack.top--]; } // Function to implement legal movement between // two poles void moveDisksBetweenTwoPoles(Stack src, Stack dest, char s, char d) { int pole1TopDisk = pop(src); int pole2TopDisk = pop(dest); // When pole 1 is empty if (pole1TopDisk == Integer.MIN_VALUE) { push(src, pole2TopDisk); moveDisk(d, s, pole2TopDisk); } // When pole2 pole is empty else if (pole2TopDisk == Integer.MIN_VALUE) { push(dest, pole1TopDisk); moveDisk(s, d, pole1TopDisk); } // When top disk of pole1 > top disk of pole2 else if (pole1TopDisk > pole2TopDisk) { push(src, pole1TopDisk); push(src, pole2TopDisk); moveDisk(d, s, pole2TopDisk); } // When top disk of pole1 < top disk of pole2 else { push(dest, pole2TopDisk); push(dest, pole1TopDisk); moveDisk(s, d, pole1TopDisk); } } // Function to show the movement of disks void moveDisk(char fromPeg, char toPeg, int disk) { System.out.println("Move the disk "+disk + " from "+fromPeg+" to "+toPeg); } // Function to implement TOH puzzle void tohIterative(int num_of_disks, Stack src, Stack aux, Stack dest) { int i, total_num_of_moves; char s = 'S', d = 'D', a = 'A'; // If number of disks is even, then interchange // destination pole and auxiliary pole if (num_of_disks % 2 == 0) { char temp = d; d = a; a = temp; } total_num_of_moves = (int) (Math.pow(2, num_of_disks) - 1); // Larger disks will be pushed first for (i = num_of_disks; i >= 1; i--) push(src, i); for (i = 1; i <= total_num_of_moves; i++) { if (i % 3 == 1) moveDisksBetweenTwoPoles(src, dest, s, d); else if (i % 3 == 2) moveDisksBetweenTwoPoles(src, aux, s, a); else if (i % 3 == 0) moveDisksBetweenTwoPoles(aux, dest, a, d); } } // Driver Program to test above functions public static void main(String[] args) { // Input: number of disks int num_of_disks = 3; TOH ob = new TOH(); Stack src, dest, aux; // Create three stacks of size 'num_of_disks' // to hold the disks src = ob.createStack(num_of_disks); dest = ob.createStack(num_of_disks); aux = ob.createStack(num_of_disks); ob.tohIterative(num_of_disks, src, aux, dest); } }
Remove duplicates from an unsorted singly linked list
Write a removeDuplicates() function which takes a list and deletes any duplicate nodes from the list. The list is not sorted. For example if the linked list is 12->11->12->21->41->43->21 then removeDuplicates() should convert the list to 12->11->21->41->43. METHOD 3 (Use Hashing) We traverse the link list from head to end. For every newly encountered element, we check whether it is in the hash table: if yes, we remove it; otherwise we put it in the hash table.
Check if a singly linked list is a palindrome
METHOD 2 (By reversing the list) This method takes O(n) time and O(1) extra space. 1) Get the middle of the linked list. 2) Reverse the second half of the linked list. 3) Check if the first half and second half are identical. 4) Construct the original linked list by reversing the second half again and attaching it back to the first half To divide the list in two halves, method 2 of this post is used. When number of nodes are even, the first and second half contain exactly half nodes. The challenging thing in this method is to handle the case when number of nodes are odd. We don't want the middle node as part of any of the lists as we are going to compare them for equality. For odd case, we use a separate variable 'midnode'. /* Java program to check if linked list is palindrome */ class LinkedList { Node head; // head of list Node slow_ptr, fast_ptr,second_half; /* Linked list Node*/ class Node { char data; Node next; Node(char d) { data = d; next = null; } } /* Function to check if given linked list is palindrome or not */ boolean isPalindrome(Node head) { slow_ptr = head; fast_ptr = head; Node prev_of_slow_ptr = head; Node midnode = null; // To handle odd size list boolean res = true; // initialize result if (head != null && head.next != null) { /* Get the middle of the list. Move slow_ptr by 1 and fast_ptrr by 2, slow_ptr will have the middle node */ while (fast_ptr != null && fast_ptr.next != null) { fast_ptr = fast_ptr.next.next; /*We need previous of the slow_ptr for linked lists with odd elements */ prev_of_slow_ptr = slow_ptr; slow_ptr = slow_ptr.next; } /* fast_ptr would become NULL when there are even elements in the list and not NULL for odd elements. We need to skip the middle node for odd case and store it somewhere so that we can restore the original list */ if (fast_ptr != null) { midnode = slow_ptr; slow_ptr = slow_ptr.next; } // Now reverse the second half and compare it with first half second_half = slow_ptr; prev_of_slow_ptr.next = null; // NULL terminate first half reverse(); // Reverse the second half res = compareLists(head, second_half); // compare /* Construct the original list back */ reverse(); // Reverse the second half again if (midnode != null) { // If there was a mid node (odd size case) which // was not part of either first half or second half. prev_of_slow_ptr.next = midnode; midnode.next = second_half; } else prev_of_slow_ptr.next = second_half; } return res; } /* Function to reverse the linked list Note that this function may change the head */ void reverse() { Node prev = null; Node current = second_half; Node next; while (current != null) { next = current.next; current.next = prev; prev = current; current = next; } second_half = prev; } /* Function to check if two input lists have same data*/ boolean compareLists(Node head1, Node head2) { Node temp1 = head1; Node temp2 = head2; while (temp1 != null && temp2 != null) { if (temp1.data == temp2.data) { temp1 = temp1.next; temp2 = temp2.next; } else return false; } /* Both are empty reurn 1*/ if (temp1 == null && temp2 == null) return true; /* Will reach here when one is NULL and other is not */ return false; } /* Push a node to linked list. Note that this function changes the head */ public void push(char new_data) { /* Allocate the Node & Put in the data */ Node new_node = new Node(new_data); /* link the old list off the new one */ new_node.next = head; /* Move the head to point to new Node */ head = new_node; } // A utility function to print a given linked list void printList(Node ptr) { while (ptr != null) { System.out.print(ptr.data + "->"); ptr = ptr.next; } System.out.println("NULL"); } /* Driver program to test the above functions */ public static void main(String[] args) { /* Start with the empty list */ LinkedList llist = new LinkedList(); char str[] = {'a', 'b', 'a', 'c', 'a', 'b', 'a'}; String string = new String(str); for (int i = 0; i< 7 ; i++) { llist.push(str[i]); llist.printList(llist.head); if (llist.isPalindrome(llist.head) != false) { System.out.println("Is Palindrome"); System.out.println(""); } else { System.out.println("Not Palindrome"); System.out.println(""); } } } }
Circular Linked List Java
/* * Java Program to Implement Circular Singly Linked List */ import java.util.Scanner; /* Class Node */ class Node { protected int data; protected Node link; /* Constructor */ public Node() { link = null; data = 0; } /* Constructor */ public Node(int d,Node n) { data = d; link = n; } /* Function to set link to next Node */ public void setLink(Node n) { link = n; } /* Function to set data to current Node */ public void setData(int d) { data = d; } /* Function to get link to next node */ public Node getLink() { return link; } /* Function to get data from current Node */ public int getData() { return data; } } /* Class linkedList */ class linkedList { protected Node start ; protected Node end ; public int size ; /* Constructor */ public linkedList() { start = null; end = null; size = 0; } /* Function to check if list is empty */ public boolean isEmpty() { return start == null; } /* Function to get size of the list */ public int getSize() { return size; } /* Function to insert element at the begining */ public void insertAtStart(int val) { Node nptr = new Node(val,null); nptr.setLink(start); if(start == null) { start = nptr; nptr.setLink(start); end = start; } else { end.setLink(nptr); start = nptr; } size++ ; } /* Function to insert element at end */ public void insertAtEnd(int val) { Node nptr = new Node(val,null); nptr.setLink(start); if(start == null) { start = nptr; nptr.setLink(start); end = start; } else { end.setLink(nptr); end = nptr; } size++ ; } /* Function to insert element at position */ public void insertAtPos(int val , int pos) { Node nptr = new Node(val,null); Node ptr = start; pos = pos - 1 ; for (int i = 1; i < size - 1; i++) { if (i == pos) { Node tmp = ptr.getLink() ; ptr.setLink( nptr ); nptr.setLink(tmp); break; } ptr = ptr.getLink(); } size++ ; } /* Function to delete element at position */ public void deleteAtPos(int pos) { if (size == 1 && pos == 1) { start = null; end = null; size = 0; return ; } if (pos == 1) { start = start.getLink(); end.setLink(start); size--; return ; } if (pos == size) { Node s = start; Node t = start; while (s != end) { t = s; s = s.getLink(); } end = t; end.setLink(start); size --; return; } Node ptr = start; pos = pos - 1 ; for (int i = 1; i < size - 1; i++) { if (i == pos) { Node tmp = ptr.getLink(); tmp = tmp.getLink(); ptr.setLink(tmp); break; } ptr = ptr.getLink(); } size-- ; } /* Function to display contents */ public void display() { System.out.print("\nCircular Singly Linked List = "); Node ptr = start; if (size == 0) { System.out.print("empty\n"); return; } if (start.getLink() == start) { System.out.print(start.getData()+ "->"+ptr.getData()+ "\n"); return; } System.out.print(start.getData()+ "->"); ptr = start.getLink(); while (ptr.getLink() != start) { System.out.print(ptr.getData()+ "->"); ptr = ptr.getLink(); } System.out.print(ptr.getData()+ "->"); ptr = ptr.getLink(); System.out.print(ptr.getData()+ "\n"); } } /* Class CircularSinglyLinkedList */ public class CircularSinglyLinkedList { public static void main(String[] args) { Scanner scan = new Scanner(System.in); /* Creating object of linkedList */ linkedList list = new linkedList(); System.out.println("Circular Singly Linked List Test\n"); char ch; /* Perform list operations */ do { System.out.println("\nCircular Singly Linked List Operations\n"); System.out.println("1. insert at begining"); System.out.println("2. insert at end"); System.out.println("3. insert at position"); System.out.println("4. delete at position"); System.out.println("5. check empty"); System.out.println("6. get size"); int choice = scan.nextInt(); switch (choice) { case 1 : System.out.println("Enter integer element to insert"); list.insertAtStart( scan.nextInt() ); break; case 2 : System.out.println("Enter integer element to insert"); list.insertAtEnd( scan.nextInt() ); break; case 3 : System.out.println("Enter integer element to insert"); int num = scan.nextInt() ; System.out.println("Enter position"); int pos = scan.nextInt() ; if (pos <= 1 || pos > list.getSize() ) System.out.println("Invalid position\n"); else list.insertAtPos(num, pos); break; case 4 : System.out.println("Enter position"); int p = scan.nextInt() ; if (p < 1 || p > list.getSize() ) System.out.println("Invalid position\n"); else list.deleteAtPos(p); break; case 5 : System.out.println("Empty status = "+ list.isEmpty()); break; case 6 : System.out.println("Size = "+ list.getSize() +" \n"); break; default : System.out.println("Wrong Entry \n "); break; } /* Display List */ list.display(); System.out.println("\nDo you want to continue (Type y or n) \n"); ch = scan.next().charAt(0); } while (ch == 'Y'|| ch == 'y'); } }
Expression Evaluation Code
/* A Java program to evaluate a given expression where tokens are separated by space. Test Cases: "10 + 2 * 6" ---> 22 "100 * 2 + 12" ---> 212 "100 * ( 2 + 12 )" ---> 1400 "100 * ( 2 + 12 ) / 14" ---> 100 */ import java.util.Stack; public class EvaluateString { public static int evaluate(String expression) { char[] tokens = expression.toCharArray(); // Stack for numbers: 'values' Stack<Integer> values = new Stack<Integer>(); // Stack for Operators: 'ops' Stack<Character> ops = new Stack<Character>(); for (int i = 0; i < tokens.length; i++) { // Current token is a whitespace, skip it if (tokens[i] == ' ') continue; // Current token is a number, push it to stack for numbers if (tokens[i] >= '0' && tokens[i] <= '9') { StringBuffer sbuf = new StringBuffer(); // There may be more than one digits in number while (i < tokens.length && tokens[i] >= '0' && tokens[i] <= '9') sbuf.append(tokens[i++]); values.push(Integer.parseInt(sbuf.toString())); } // Current token is an opening brace, push it to 'ops' else if (tokens[i] == '(') ops.push(tokens[i]); // Closing brace encountered, solve entire brace else if (tokens[i] == ')') { while (ops.peek() != '(') values.push(applyOp(ops.pop(), values.pop(), values.pop())); ops.pop(); } // Current token is an operator. else if (tokens[i] == '+' || tokens[i] == '-' || tokens[i] == '*' || tokens[i] == '/') { // While top of 'ops' has same or greater precedence to current // token, which is an operator. Apply operator on top of 'ops' // to top two elements in values stack while (!ops.empty() && hasPrecedence(tokens[i], ops.peek())) values.push(applyOp(ops.pop(), values.pop(), values.pop())); // Push current token to 'ops'. ops.push(tokens[i]); } } // Entire expression has been parsed at this point, apply remaining // ops to remaining values while (!ops.empty()) values.push(applyOp(ops.pop(), values.pop(), values.pop())); // Top of 'values' contains result, return it return values.pop(); } // Returns true if 'op2' has higher or same precedence as 'op1', // otherwise returns false. public static boolean hasPrecedence(char op1, char op2) { if (op2 == '(' || op2 == ')') return false; if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) return false; else return true; } // A utility method to apply an operator 'op' on operands 'a' // and 'b'. Return the result. public static int applyOp(char op, int b, int a) { switch (op) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': if (b == 0) throw new UnsupportedOperationException("Cannot divide by zero"); return a / b; } return 0; } // Driver method to test above methods public static void main(String[] args) { System.out.println(EvaluateString.evaluate("10 + 2 * 6")); System.out.println(EvaluateString.evaluate("100 * 2 + 12")); System.out.println(EvaluateString.evaluate("100 * ( 2 + 12 )")); System.out.println(EvaluateString.evaluate("100 * ( 2 + 12 ) / 14")); } }
Doubly Linked List Insertion
// A complete working Java program to demonstrate all // Class for Doubly Linked List public class DLL { Node head; // head of list /* Doubly Linked list Node*/ class Node { int data; Node prev; Node next; // Constructor to create a new node // next and prev is by default initialized as null Node(int d){data=d;} } //Adding a node at the front of the list public void push(int new_data) { /* 1. allocate node * 2. put in the data */ Node new_Node = new Node(new_data); /* 3. Make next of new node as head and previous as NULL */ new_Node.next = head; new_Node.prev = null; /* 4. change prev of head node to new node */ if(head != null) head.prev = new_Node; /* 5. move the head to point to the new node */ head = new_Node; } /* Given a node as prev_node, insert a new node after the given node */ public void InsertAfter(Node prev_Node,int new_data) { /*1. check if the given prev_node is NULL */ if(prev_Node == null) { System.out.println("The given previous node cannot be NULL "); return; } /* 2. allocate node * 3. put in the data */ Node new_node = new Node(new_data); /* 4. Make next of new node as next of prev_node */ new_node.next = prev_Node.next; /* 5. Make the next of prev_node as new_node */ prev_Node.next = new_node; /* 6. Make prev_node as previous of new_node */ new_node.prev = prev_Node; /* 7. Change previous of new_node's next node */ if(new_node.next != null) new_node.next.prev = new_node; } //Add a node at the end of the list void append(int new_data) { /* 1. allocate node * 2. put in the data */ Node new_node = new Node(new_data); Node last = head;/* used in step 5*/ /* 3. This new node is going to be the last node, so * make next of it as NULL*/ new_node.next = null; /* 4. If the Linked List is empty, then make the new * node as head */ if(head == null) { new_node.prev = null; head = new_node; return; } /* 5. Else traverse till the last node */ while(last.next != null) last = last.next; /* 6. Change the next of last node */ last.next = new_node; /* 7. Make last node as previous of new node */ new_node.prev = last; } // This function prints contents of linked list starting from the given node public void printlist(Node node) { Node last = null; System.out.println("Traversal in forward Direction"); while(node != null) { System.out.print(node.data + " "); last = node; node = node.next; } System.out.println(); System.out.println("Traversal in reverse direction"); while (last != null) { System.out.print(last.data + " "); last = last.prev; } } /* Drier program to test above functions*/ public static void main(String[] args) { /* Start with the empty list */ DLL dll = new DLL(); // Insert 6. So linked list becomes 6->NULL dll.append(6); // Insert 7 at the beginning. So linked list becomes 7->6->NULL dll.push(7); // Insert 1 at the beginning. So linked list becomes 1->7->6->NULL dll.push(1); // Insert 4 at the end. So linked list becomes 1->7->6->4->NULL dll.append(4); // Insert 8, after 7. So linked list becomes 1->7->8->6->4->NULL dll.InsertAfter(dll.head.next, 8); System.out.println("Created DLL is: "); dll.printlist(dll.head); } }
Singly Linked List Insertion
// A complete working Java program to demonstrate all insertion methods // on linked list class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node next; Node(int d) {data = d; next = null; } } /* Inserts a new Node at front of the list. */ public void push(int new_data) { /* 1 & 2: Allocate the Node & Put in the data*/ Node new_node = new Node(new_data); /* 3. Make next of new Node as head */ new_node.next = head; /* 4. Move the head to point to new Node */ head = new_node; } /* Inserts a new node after the given prev_node. */ public void insertAfter(Node prev_node, int new_data) { /* 1. Check if the given Node is null */ if (prev_node == null) { System.out.println("The given previous node cannot be null"); return; } /* 2 & 3: Allocate the Node & Put in the data*/ Node new_node = new Node(new_data); /* 4. Make next of new Node as next of prev_node */ new_node.next = prev_node.next; /* 5. make next of prev_node as new_node */ prev_node.next = new_node; } /* Appends a new node at the end. This method is defined inside LinkedList class shown above */ public void append(int new_data) { /* 1. Allocate the Node & 2. Put in the data 3. Set next as null */ Node new_node = new Node(new_data); /* 4. If the Linked List is empty, then make the new node as head */ if (head == null) { head = new Node(new_data); return; } /* 4. This new node is going to be the last node, so make next of it as null */ new_node.next = null; /* 5. Else traverse till the last node */ Node last = head; while (last.next != null) last = last.next; /* 6. Change the next of last node */ last.next = new_node; return; } /* This function prints contents of linked list starting from the given node */ public void printList() { Node tnode = head; while (tnode != null) { System.out.print(tnode.data+" "); tnode = tnode.next; } } /* Driver program to test above functions. Ideally this function should be in a separate user class. It is kept here to keep code compact */ public static void main(String[] args) { /* Start with the empty list */ LinkedList llist = new LinkedList(); // Insert 6. So linked list becomes 6->NUllist llist.append(6); // Insert 7 at the beginning. So linked list becomes // 7->6->NUllist llist.push(7); // Insert 1 at the beginning. So linked list becomes // 1->7->6->NUllist llist.push(1); // Insert 4 at the end. So linked list becomes // 1->7->6->4->NUllist llist.append(4); // Insert 8, after 7. So linked list becomes // 1->7->8->6->4->NUllist llist.insertAfter(llist.head.next, 8); System.out.println("\nCreated Linked list is: "); llist.printList(); } }
Singly Linked List Deletion
// A complete working Java program to demonstrate deletion in singly // linked list class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node next; Node(int d) { data = d; next = null; } } /* Given a key, deletes the first occurrence of key in linked list */ void deleteNode(int key) { // Store head node Node temp = head, prev = null; // If head node itself holds the key to be deleted if (temp != null && temp.data == key) { head = temp.next; // Changed head return; } // Search for the key to be deleted, keep track of the // previous node as we need to change temp.next while (temp != null && temp.data != key) { prev = temp; temp = temp.next; } // If key was not present in linked list if (temp == null) return; // Unlink the node from linked list prev.next = temp.next; } /* Inserts a new Node at front of the list. */ public void push(int new_data) { Node new_node = new Node(new_data); new_node.next = head; head = new_node; } /* This function prints contents of linked list starting from the given node */ public void printList() { Node tnode = head; while (tnode != null) { System.out.print(tnode.data+" "); tnode = tnode.next; } } /* Drier program to test above functions. Ideally this function should be in a separate user class. It is kept here to keep code compact */ public static void main(String[] args) { LinkedList llist = new LinkedList(); llist.push(7); llist.push(1); llist.push(3); llist.push(2); System.out.println("\nCreated Linked list is:"); llist.printList(); llist.deleteNode(1); // Delete node at position 4 System.out.println("\nLinked List after Deletion at position 4:"); llist.printList(); } }
Linked list implementation of a queue
// Java program for linked-list implementation of queue // A linked list (LL) node to store a queue entry class QNode { int key; QNode next; // constructor to create a new linked list node public QNode(int key) { this.key = key; this.next = null; } } // A class to represent a queue //The queue, front stores the front node of LL and rear stores ths //last node of LL class Queue { QNode front, rear; public Queue() { this.front = this.rear = null; } // Method to add an key to the queue. void enqueue(int key) { // Create a new LL node QNode temp = new QNode(key); // If queue is empty, then new node is front and rear both if (this.rear == null) { this.front = this.rear = temp; return; } // Add the new node at the end of queue and change rear this.rear.next = temp; this.rear = temp; } // Method to remove an key from queue. QNode dequeue() { // If queue is empty, return NULL. if (this.front == null) return null; // Store previous front and move front one node ahead QNode temp = this.front; this.front = this.front.next; // If front becomes NULL, then change rear also as NULL if (this.front == null) this.rear = null; return temp; } } // Driver class public class Test { public static void main(String[] args) { Queue q=new Queue(); q.enqueue(10); q.enqueue(20); q.dequeue(); q.dequeue(); q.enqueue(30); q.enqueue(40); q.enqueue(50); System.out.println("Dequeued item is "+ q.dequeue().key); } }
Doubly Linked List Deletion
// Java program to delete a node from doubly linked list class LinkedList { static Node head = null; class Node { int data; Node next, prev; Node(int d) { data = d; next = prev = null; } } /*Function to delete a node in a Doubly Linked List. head_ref --> pointer to head node pointer. del --> pointer to node to be deleted. */ void deleteNode(Node head_ref, Node del) { /* base case */ if (head == null || del == null) { return; } /* If node to be deleted is head node */ if (head == del) { head = del.next; } /* Change next only if node to be deleted is NOT the last node */ if (del.next != null) { del.next.prev = del.prev; } /* Change prev only if node to be deleted is NOT the first node */ if (del.prev != null) { del.prev.next = del.next; } /* Finally, free the memory occupied by del*/ return; } /* UTILITY FUNCTIONS */ /* Function to insert a node at the beginning of the Doubly Linked List */ void push(Node head_ref, int new_data) { /* allocate node */ Node new_node = new Node(new_data); /* since we are adding at the begining, prev is always NULL */ new_node.prev = null; /* link the old list off the new node */ new_node.next = (head); /* change prev of head node to new node */ if ((head) != null) { (head).prev = new_node; } /* move the head to point to the new node */ (head) = new_node; } /*Function to print nodes in a given doubly linked list This function is same as printList() of singly linked lsit */ void printList(Node node) { while (node != null) { System.out.print(node.data + " "); node = node.next; } } public static void main(String[] args) { LinkedList list = new LinkedList(); /* Let us create the doubly linked list 10<->8<->4<->2 */ list.push(head, 2); list.push(head, 4); list.push(head, 8); list.push(head, 10); System.out.println("Original Linked list "); list.printList(head); /* delete nodes from the doubly linked list */ list.deleteNode(head, head); /*delete first node*/ list.deleteNode(head, head.next); /*delete middle node*/ list.deleteNode(head, head.next); /*delete last node*/ System.out.println(""); /* Modified linked list will be NULL<-8->NULL */ System.out.println("Modified Linked List"); list.printList(head); } }
Reverse a doubly linked list
// Java program to reverse a doubly linked list class LinkedList { static Node head; static class Node { int data; Node next, prev; Node(int d) { data = d; next = prev = null; } } /* Function to reverse a Doubly Linked List */ void reverse() { Node temp = null; Node current = head; /* swap next and prev for all nodes of doubly linked list */ while (current != null) { temp = current.prev; current.prev = current.next; current.next = temp; current = current.prev; } /* Before changing head, check for the cases like empty list and list with only one node */ if (temp != null) { head = temp.prev; } } /* UTILITY FUNCTIONS */ /* Function to insert a node at the beginging of the Doubly Linked List */ void push(int new_data) { /* allocate node */ Node new_node = new Node(new_data); /* since we are adding at the begining, prev is always NULL */ new_node.prev = null; /* link the old list off the new node */ new_node.next = head; /* change prev of head node to new node */ if (head != null) { head.prev = new_node; } /* move the head to point to the new node */ head = new_node; } /* Function to print nodes in a given doubly linked list This function is same as printList() of singly linked lsit */ void printList(Node node) { while (node != null) { System.out.print(node.data + " "); node = node.next; } } public static void main(String[] args) { LinkedList list = new LinkedList(); /* Let us create a sorted linked list to test the functions Created linked list will be 10->8->4->2 */ list.push(2); list.push(4); list.push(8); list.push(10); System.out.println("Original linked list "); list.printList(head); list.reverse(); System.out.println(""); System.out.println("The reversed Linked List is "); list.printList(head); } }
Binary Search Tree (Deletion)
1) Node to be deleted is leaf: Simply remove from the tree. 2) Node to be deleted has only one child: Copy the child to the node and delete the child 3) Node to be deleted has two children: Find inorder successor of the node. Copy contents of the inorder successor to the node and delete the inorder successor. Note that inorder predecessor can also be used. The important thing to note is, inorder successor is needed only when right child is not empty. In this particular case, inorder successor can be obtained by finding the minimum value in right child of the node. // Java program to demonstrate delete operation in binary search tree class BinarySearchTree { /* Class containing left and right child of current node and key value*/ class Node { int key; Node left, right; public Node(int item) { key = item; left = right = null; } } // Root of BST Node root; // Constructor BinarySearchTree() { root = null; } // This method mainly calls deleteRec() void deleteKey(int key) { root = deleteRec(root, key); } /* A recursive function to insert a new key in BST */ Node deleteRec(Node root, int key) { /* Base Case: If the tree is empty */ if (root == null) return root; /* Otherwise, recur down the tree */ if (key < root.key) root.left = deleteRec(root.left, key); else if (key > root.key) root.right = deleteRec(root.right, key); // if key is same as root's key, then This is the node // to be deleted else { // node with only one child or no child if (root.left == null) return root.right; else if (root.right == null) return root.left; // node with two children: Get the inorder successor (smallest // in the right subtree) root.key = minValue(root.right); // Delete the inorder successor root.right = deleteRec(root.right, root.key); } return root; } int minValue(Node root) { int minv = root.key; while (root.left != null) { minv = root.left.key; root = root.left; } return minv; } // This method mainly calls insertRec() void insert(int key) { root = insertRec(root, key); } /* A recursive function to insert a new key in BST */ Node insertRec(Node root, int key) { /* If the tree is empty, return a new node */ if (root == null) { root = new Node(key); return root; } /* Otherwise, recur down the tree */ if (key < root.key) root.left = insertRec(root.left, key); else if (key > root.key) root.right = insertRec(root.right, key); /* return the (unchanged) node pointer */ return root; } // This method mainly calls InorderRec() void inorder() { inorderRec(root); } // A utility function to do inorder traversal of BST void inorderRec(Node root) { if (root != null) { inorderRec(root.left); System.out.print(root.key + " "); inorderRec(root.right); } } // Driver Program to test above functions public static void main(String[] args) { BinarySearchTree tree = new BinarySearchTree(); /* Let us create following BST 50 / \ 30 70 / \ / \ 20 40 60 80 */ tree.insert(50); tree.insert(30); tree.insert(20); tree.insert(40); tree.insert(70); tree.insert(60); tree.insert(80); System.out.println("Inorder traversal of the given tree"); tree.inorder(); System.out.println("\nDelete 20"); tree.deleteKey(20); System.out.println("Inorder traversal of the modified tree"); tree.inorder(); System.out.println("\nDelete 30"); tree.deleteKey(30); System.out.println("Inorder traversal of the modified tree"); tree.inorder(); System.out.println("\nDelete 50"); tree.deleteKey(50); System.out.println("Inorder traversal of the modified tree"); tree.inorder(); } }
Split a circular linked list in 2 halves
1) Store the mid and last pointers of the circular linked list using tortoise and hare algorithm. 2) Make the second half circular. 3) Make the first half circular. 4) Set head (or start) pointers of the two linked lists. // Java program to delete a node from doubly linked list class LinkedList { static Node head, head1, head2; static class Node { int data; Node next, prev; Node(int d) { data = d; next = prev = null; } } /* Function to split a list (starting with head) into two lists. head1_ref and head2_ref are references to head nodes of the two resultant linked lists */ void splitList() { Node slow_ptr = head; Node fast_ptr = head; if (head == null) { return; } /* If there are odd nodes in the circular list then fast_ptr->next becomes head and for even nodes fast_ptr->next->next becomes head */ while (fast_ptr.next != head && fast_ptr.next.next != head) { fast_ptr = fast_ptr.next.next; slow_ptr = slow_ptr.next; } /* If there are even elements in list then move fast_ptr */ if (fast_ptr.next.next == head) { fast_ptr = fast_ptr.next; } /* Set the head pointer of first half */ head1 = head; /* Set the head pointer of second half */ if (head.next != head) { head2 = slow_ptr.next; } /* Make second half circular */ fast_ptr.next = slow_ptr.next; /* Make first half circular */ slow_ptr.next = head; } /* Function to print nodes in a given singly linked list */ void printList(Node node) { Node temp = node; if (node != null) { do { System.out.print(temp.data + " "); temp = temp.next; } while (temp != node); } } public static void main(String[] args) { LinkedList list = new LinkedList(); //Created linked list will be 12->56->2->11 list.head = new Node(12); list.head.next = new Node(56); list.head.next.next = new Node(2); list.head.next.next.next = new Node(11); list.head.next.next.next.next = list.head; System.out.println("Original Circular Linked list "); list.printList(head); // Split the list list.splitList(); System.out.println(""); System.out.println("First Circular List "); list.printList(head1); System.out.println(""); System.out.println("Second Circular List "); list.printList(head2); } }
Doubly Linked List
A Doubly Linked List (DLL) contains an extra pointer, typically called previous pointer, together with next pointer and data which are there in singly linked list.
A program to check if a binary tree is BST or not
A binary search tree (BST) is a node based binary tree data structure which has the following properties. • The left subtree of a node contains only nodes with keys less than the node's key. • The right subtree of a node contains only nodes with keys greater than the node's key. • Both the left and right subtrees must also be binary search trees.
Array Advantages and Disadvantages
Advantages of using arrays: Arrays allow random access of elements. This makes accessing elements by position faster. Arrays have better cache locality that can make a pretty big difference in performance. Disadvantages 1) The size of the arrays is fixed: So we must know the upper limit on the number of elements in advance. Also, generally, the allocated memory is equal to the upper limit irrespective of the usage. 2) Inserting a new element in an array of elements is expensive, because room has to be created for the new elements and to create room existing elements have to shifted.
Doubly Linked List Advantages/Disadvantages
Advantages over singly linked list 1) A DLL can be traversed in both forward and backward direction. 2) The delete operation in DLL is more efficient if pointer to the node to be deleted is given. In singly linked list, to delete a node, pointer to the previous node is needed. To get this previous node, sometimes the list is traversed. In DLL, we can get the previous node using previous pointer. Disadvantages over singly linked list 1) Every node of DLL Require extra space for an previous pointer. It is possible to implement DLL with single pointer though (See this and this). 2) All operations require an extra pointer previous to be maintained. For example, in insertion, we need to modify previous pointers together with next pointers. For example in following functions for insertions at different positions, we need 1 or 2 extra steps to set previous pointer.
Binary Search Tree
Binary Search Tree, is a node-based binary tree data structure which has the following properties: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. The left and right subtree each must also be a binary search tree. There must be no duplicate nodes. Searching a key To search a given key in Bianry Search Tree, we first compare it with root, if the key is present at root, we return root. If key is greater than root's key, we recur for right subtree of root node. Otherwise we recur for left subtree.
Breadth First Traversal for a Graph
Breadth First Traversal (or Search) for a graph is similar to Breadth First Traversal of a tree (See method 2 of this post). The only catch here is, unlike trees, graphs may contain cycles, so we may come to the same node again. To avoid processing a node more than once, we use a boolean visited array. For simplicity, it is assumed that all vertices are reachable from the starting vertex. // Java program to print BFS traversal from a given source vertex. // BFS(int s) traverses vertices reachable from s. import java.io.*; import java.util.*; // This class represents a directed graph using adjacency list // representation class Graph { private int V; // No. of vertices private LinkedList<Integer> adj[]; //Adjacency Lists // Constructor Graph(int v) { V = v; adj = new LinkedList[v]; for (int i=0; i<v; ++i) adj[i] = new LinkedList(); } // Function to add an edge into the graph void addEdge(int v,int w) { adj[v].add(w); } // prints BFS traversal from a given source s void BFS(int s) { // Mark all the vertices as not visited(By default // set as false) boolean visited[] = new boolean[V]; // Create a queue for BFS LinkedList<Integer> queue = new LinkedList<Integer>(); // Mark the current node as visited and enqueue it visited[s]=true; queue.add(s); while (queue.size() != 0) { // Dequeue a vertex from queue and print it s = queue.poll(); System.out.print(s+" "); // Get all adjacent vertices of the dequeued vertex s // If a adjacent has not been visited, then mark it // visited and enqueue it Iterator<Integer> i = adj[s].listIterator(); while (i.hasNext()) { int n = i.next(); if (!visited[n]) { visited[n] = true; queue.add(n); } } } } // Driver method to public static void main(String args[]) { Graph g = new Graph(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 0); g.addEdge(2, 3); g.addEdge(3, 3); System.out.println("Following is Breadth First Traversal "+ "(starting from vertex 2)"); g.BFS(2); } }
Circular Linked List
Circular linked list is a linked list where all nodes are connected to form a circle. There is no NULL at the end. A circular linked list can be a singly circular linked list or doubly circular linked list. Advantages of Circular Linked Lists: 1) Any node can be a starting point. We can traverse the whole list by starting from any point. We just need to stop when the first visited node is visited again. 2) Useful for implementation of queue. Unlike this implementation, we don't need to maintain two pointers for front and rear if we use circular linked list. We can maintain a pointer to the last inserted node and front can always be obtained as next of last. 3) Circular lists are useful in applications to repeatedly go around the list. For example, when multiple applications are running on a PC, it is common for the operating system to put the running applications on a list and then to cycle through them, giving each of them a slice of time to execute, and then making them wait while the CPU is given to another application. It is convenient for the operating system to use a circular list so that when it reaches the end of the list it can cycle around to the front of the list. 4) Circular Doubly Linked Lists are used for implementation of advanced data structures like Fibonacci Heap.
BST Advantages
Following are some important points in favor of BSTs. We can get all keys in sorted order by just doing Inorder Traversal of BST. This is not a natural operation in Hash Tables and requires extra efforts. Doing order statistics, finding closest lower and greater elements, doing range queries are easy to do with BSTs. Like sorting, these operations are not a natural operation with Hash Tables. BSTs are easy to implement compared to hashing, we can easily implement our own customized BST. To implement Hashing, we generally rely on libraries provided by programming languages. With BSTs, all operations are guaranteed to work in O(Logn) time. But with Hashing, Θ(1) is average time and some particular operations may be costly, especially when table resizing happens.
Expression Evaluation
Evaluate an expression represented by a String. Expression can contain parentheses, you can assume parentheses are well-matched. For simplicity, you can assume only binary operations allowed are +, -, *, and /. Arithmetic Expressions can be written in one of three forms: Infix Notation: Operators are written between the operands they operate on, e.g. 3 + 4 . Prefix Notation: Operators are written before the operands, e.g + 3 4 Postfix Notation: Operators are written after operands. 1. While there are still tokens to be read in, 1.1 Get the next token. 1.2 If the token is: 1.2.1 A number: push it onto the value stack. 1.2.2 A variable: get its value, and push onto the value stack. 1.2.3 A left parenthesis: push it onto the operator stack. 1.2.4 A right parenthesis: 1 While the thing on top of the operator stack is not a left parenthesis, 1 Pop the operator from the operator stack. 2 Pop the value stack twice, getting two operands. 3 Apply the operator to the operands, in the correct order. 4 Push the result onto the value stack. 2 Pop the left parenthesis from the operator stack, and discard it. 1.2.5 An operator (call it thisOp): 1 While the operator stack is not empty, and the top thing on the operator stack has the same or greater precedence as thisOp, 1 Pop the operator from the operator stack. 2 Pop the value stack twice, getting two operands. 3 Apply the operator to the operands, in the correct order. 4 Push the result onto the value stack. 2 Push thisOp onto the operator stack. 2. While the operator stack is not empty, 1 Pop the operator from the operator stack. 2 Pop the value stack twice, getting two operands. 3 Apply the operator to the operands, in the correct order. 4 Push the result onto the value stack. 3. At this point the operator stack should be empty, and the value stack should have only one value in it, which is the final result.
Evaluate Postfix Expression
Following is algorithm for evaluation postfix expressions. 1) Create a stack to store operands (or values). 2) Scan the given expression and do following for every scanned element. .....a) If the element is a number, push it into the stack .....b) If the element is a operator, pop operands for the operator from stack. Evaluate the operator and push the result back to the stack 3) When the expression is ended, the number in the stack is the final answer Example: Let the given expression be "2 3 1 * + 9 -". We scan all elements one by one. 1) Scan '2', it's a number, so push it to stack. Stack contains '2' 2) Scan '3', again a number, push it to stack, stack now contains '2 3' (from bottom to top) 3) Scan '1', again a number, push it to stack, stack now contains '2 3 1' 4) Scan '*', it's an operator, pop two operands from stack, apply the * operator on operands, we get 3*1 which results in 3. We push the result '3' to stack. Stack now becomes '2 3'. 5) Scan '+', it's an operator, pop two operands from stack, apply the + operator on operands, we get 3 + 2 which results in 5. We push the result '5' to stack. Stack now becomes '5'. 6) Scan '9', it's a number, we push it to the stack. Stack now becomes '5 9'. 7) Scan '-', it's an operator, pop two operands from stack, apply the - operator on operands, we get 5 - 9 which results in -4. We push the result '-4' to stack. Stack now becomes '-4'. 8) There are no more elements to scan, we return the top element from stack (which is the only element left in stack).
Types of Binary Trees
Full Binary Tree A Binary Tree is full if every node has 0 or 2 children. Following are examples of full binary tree. We can also say a full binary tree is a binary tree in which all nodes except leaves have two children. 18 / \ 15 30 / \ / \ 40 50 100 40 18 / \ 15 20 / \ 40 50 / \ 30 50 18 / \ 40 30 / \ 100 40 Complete Binary Tree: A Binary Tree is complete Binary Tree if all levels are completely filled except possibly the last level and the last level has all keys as left as possible Following are examples of Complete Binary Trees 18 / \ 15 30 / \ / \ 40 50 100 40 18 / \ 15 30 / \ / \ 40 50 100 40 / \ / 8 7 9 Perfect Binary Tree A Binary tree is Perfect Binary Tree in which all internal nodes have two children and all leaves are at same level. Following are examples of Perfect Binaryr Trees. 18 / \ 15 30 / \ / \ 40 50 100 40 18 / \ 15 30 Balanced Binary Tree A binary tree is balanced if height of the tree is O(Log n) where n is number of nodes. For Example, AVL tree maintain O(Log n) height by making sure that the difference between heights of left and right subtrees is 1. Red-Black trees maintain O(Log n) height by making sure that the number of Black nodes on every root to leaf paths are same and there are no adjacent red nodes. Balanced Binary Search trees are performance wise good as they provide O(log n) time for search, insert and delete. A degenerate (or pathological) tree A Tree where every internal node has one child. Such trees are performance-wise same as linked list. 10 / 20 \ 30 \ 40
Reversing a Queue
Give an algorithm for reversing a queue Q. Only following standard operations are allowed on queue. enqueue(x) : Add an item x to rear of queue. dequeue() : Remove an item from front of queue. empty() : Checks if a queue is empty or not. Examples: Input : Q = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] Output :Q = [100, 90, 80, 70, 60, 50, 40, 30, 20, 10] Input :[1, 2, 3, 4, 5] Output :[5, 4, 3, 2, 1]
Convert a BST to a Binary Tree such that sum of all greater keys is added to every key
Given a Binary Search Tree (BST), convert it to a Binary Tree such that every key of the original BST is changed to key plus sum of all greater keys in BST. Examples: Input: Root of following BST 5 / \ 2 13 Output: The given BST is converted to following Binary Tree 18 / \ 20 13 Source: Convert a BST Solution: Do reverse Inoorder traversal. Keep track of the sum of nodes visited so far. Let this sum be sum. For every node currently being visited, first add the key of this node to sum, i.e. sum = sum + node->key. Then change the key of current node to sum, i.e., node->key = sum. When a BST is being traversed in reverse Inorder, for every key currently being visited, all keys that are already visited are all greater keys.
Binary Tree to Binary Search Tree
Given a Binary Tree, convert it to a Binary Search Tree. The conversion must be done in such a way that keeps the original structure of Binary Tree. Examples. Example 1 Input: 10 / \ 2 7 / \ 8 4 Output: 8 / \ 4 10 / \ 2 7 Example 2 Input: 10 / \ 30 15 / \ 20 5 Output: 15 / \ 10 20 / \ 5 30 Following is a 3 step solution for converting Binary tree to Binary Search Tree. 1) Create a temp array arr[] that stores inorder traversal of the tree. This step takes O(n) time. 2) Sort the temp array arr[]. Time complexity of this step depends upon the sorting algorithm. In the following implementation, Quick Sort is used which takes (n^2) time. This can be done in O(nLogn) time using Heap Sort or Merge Sort. 3) Again do inorder traversal of tree and copy array elements to tree nodes one by one. This step takes O(n) time. /* A program to convert Binary Tree to Binary Search Tree */ #include<stdio.h> #include<stdlib.h> /* A binary tree node structure */ struct node { int data; struct node *left; struct node *right; }; /* A helper function that stores inorder traversal of a tree rooted with node */ void storeInorder (struct node* node, int inorder[], int *index_ptr) { // Base Case if (node == NULL) return; /* first store the left subtree */ storeInorder (node->left, inorder, index_ptr); /* Copy the root's data */ inorder[*index_ptr] = node->data; (*index_ptr)++; // increase index for next entry /* finally store the right subtree */ storeInorder (node->right, inorder, index_ptr); } /* A helper function to count nodes in a Binary Tree */ int countNodes (struct node* root) { if (root == NULL) return 0; return countNodes (root->left) + countNodes (root->right) + 1; } // Following function is needed for library function qsort() int compare (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); } /* A helper function that copies contents of arr[] to Binary Tree. This functon basically does Inorder traversal of Binary Tree and one by one copy arr[] elements to Binary Tree nodes */ void arrayToBST (int *arr, struct node* root, int *index_ptr) { // Base Case if (root == NULL) return; /* first update the left subtree */ arrayToBST (arr, root->left, index_ptr); /* Now update root's data and increment index */ root->data = arr[*index_ptr]; (*index_ptr)++; /* finally update the right subtree */ arrayToBST (arr, root->right, index_ptr); } // This function converts a given Binary Tree to BST void binaryTreeToBST (struct node *root) { // base case: tree is empty if(root == NULL) return; /* Count the number of nodes in Binary Tree so that we know the size of temporary array to be created */ int n = countNodes (root); // Create a temp array arr[] and store inorder traversal of tree in arr[] int *arr = new int[n]; int i = 0; storeInorder (root, arr, &i); // Sort the array using library function for quick sort qsort (arr, n, sizeof(arr[0]), compare); // Copy array elements back to Binary Tree i = 0; arrayToBST (arr, root, &i); // delete dynamically allocated memory to avoid meory leak delete [] arr; } /* Utility function to create a new Binary Tree node */ struct node* newNode (int data) { struct node *temp = new struct node; temp->data = data; temp->left = NULL; temp->right = NULL; return temp; } /* Utility function to print inorder traversal of Binary Tree */ void printInorder (struct node* node) { if (node == NULL) return; /* first recur on left child */ printInorder (node->left); /* then print the data of node */ printf("%d ", node->data); /* now recur on right child */ printInorder (node->right); } /* Driver function to test above functions */ int main() { struct node *root = NULL; /* Constructing tree given in the above figure 10 / \ 30 15 / \ 20 5 */ root = newNode(10); root->left = newNode(30); root->right = newNode(15); root->left->left = newNode(20); root->right->right = newNode(5); // convert Binary Tree to BST binaryTreeToBST (root); printf("Following is Inorder Traversal of the converted BST: \n"); printInorder (root); return 0; }
Sorted Linked List to Balanced BST
Given a Singly Linked List which has data members sorted in ascending order. Construct a Balanced Binary Search Tree which has same data members as the given Linked List. Examples: Input: Linked List 1->2->3 Output: A Balanced BST 2 / \ 1 3 Input: Linked List 1->2->3->4->5->6->7 Output: A Balanced BST 4 / \ 2 6 / \ / \ 1 3 4 7 Input: Linked List 1->2->3->4 Output: A Balanced BST 3 / \ 2 4 / 1 Input: Linked List 1->2->3->4->5->6 Output: A Balanced BST 4 / \ 2 6 / \ / 1 3 5 class LinkedList { /* head node of link list */ static LNode head; /* Link list Node */ class LNode { int data; LNode next, prev; LNode(int d) { data = d; next = prev = null; } } /* A Binary Tree Node */ class TNode { int data; TNode left, right; TNode(int d) { data = d; left = right = null; } } /* This function counts the number of nodes in Linked List and then calls sortedListToBSTRecur() to construct BST */ TNode sortedListToBST() { /*Count the number of nodes in Linked List */ int n = countNodes(head); /* Construct BST */ return sortedListToBSTRecur(n); } /* The main function that constructs balanced BST and returns root of it. n --> No. of nodes in the Doubly Linked List */ TNode sortedListToBSTRecur(int n) { /* Base Case */ if (n <= 0) return null; /* Recursively construct the left subtree */ TNode left = sortedListToBSTRecur(n / 2); /* head_ref now refers to middle node, make middle node as root of BST*/ TNode root = new TNode(head.data); // Set pointer to left subtree root.left = left; /* Change head pointer of Linked List for parent recursive calls */ head = head.next; /* Recursively construct the right subtree and link it with root. The number of nodes in right subtree is total nodes - nodes in left subtree - 1 (for root) */ root.right = sortedListToBSTRecur(n - n / 2 - 1); return root; } /* UTILITY FUNCTIONS */ /* A utility function that returns count of nodes in a given Linked List */ int countNodes(LNode head) { int count = 0; LNode temp = head; while (temp != null) { temp = temp.next; count++; } return count; } /* Function to insert a node at the beginging of the Doubly Linked List */ void push(int new_data) { /* allocate node */ LNode new_node = new LNode(new_data); /* since we are adding at the begining, prev is always NULL */ new_node.prev = null; /* link the old list off the new node */ new_node.next = head; /* change prev of head node to new node */ if (head != null) head.prev = new_node; /* move the head to point to the new node */ head = new_node; } /* Function to print nodes in a given linked list */ void printList(LNode node) { while (node != null) { System.out.print(node.data + " "); node = node.next; } } /* A utility function to print preorder traversal of BST */ void preOrder(TNode node) { if (node == null) return; System.out.print(node.data + " "); preOrder(node.left); preOrder(node.right); } /* Drier program to test above functions */ public static void main(String[] args) { LinkedList llist = new LinkedList(); /* Let us create a sorted linked list to test the functions Created linked list will be 7->6->5->4->3->2->1 */ llist.push(7); llist.push(6); llist.push(5); llist.push(4); llist.push(3); llist.push(2); llist.push(1); System.out.println("Given Linked List "); llist.printList(head); /* Convert List to BST */ TNode root = llist.sortedListToBST(); System.out.println(""); System.out.println("Pre-Order Traversal of constructed BST "); llist.preOrder(root); } }
Convert BST to Min Heap
Given a binary search tree which is also a complete binary tree. The problem is to convert the given BST into a Min Heap with the condition that all the values in the left subtree of a node should be less than all the values in the right subtree of the node. This condition is applied on all the nodes in the so converted Min Heap. Examples: Input : 4 / \ 2 6 / \ / \ 1 3 5 7 Output : 1 / \ 2 5 / \ / \ 3 4 6 7 The given BST has been transformed into a Min Heap. All the nodes in the Min Heap satisfies the given condition, that is, values in the left subtree of a node should be less than the values in the right subtree of the node. Create an array arr[] of size n, where n is the number of nodes in the given BST. Perform the inorder traversal of the BST and copy the node values in the arr[] in sorted order. Now perform the preorder traversal of the tree. While traversing the root during the preorder traversal, one by one copy the values from the array arr[] to the nodes.
Flattening a singly linked list
Given a linked list where every node represents a linked list and contains two pointers of its type: (i) Pointer to next node in the main list (we call it 'right' pointer in below code) (ii) Pointer to a linked list where this node is head (we call it 'down' pointer in below code). All linked lists are sorted. See the following example 5 -> 10 -> 19 -> 28 | | | | V V V V 7 20 22 35 | | | V V V 8 50 40 | | V V 30 45 Write a function flatten() to flatten the lists into a single linked list. The flattened linked list should also be sorted. For example, for the above input list, output list should be 5->7->8->10->19->20->22->28->30->35->40->45->50. // Java program for flattening a Linked List class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node right, down; Node(int data) { this.data = data; right = null; down = null; } } // An utility function to merge two sorted linked lists Node merge(Node a, Node b) { // if first linked list is empty then second // is the answer if (a == null) return b; // if second linked list is empty then first // is the result if (b == null) return a; // compare the data members of the two lonked lists // and put the larger one in the result Node result; if (a.data < b.data) { result = a; result.down = merge(a.down, b); } else { result = b; result.down = merge(a, b.down); } return result; } Node flatten(Node root) { // Base Cases if (root == null || root.right == null) return root; // recur for list on right root.right = flatten(root.right); // now merge root = merge(root, root.right); // return the root // it will be in turn merged with its left return root; } /* Utility function to insert a node at begining of the linked list */ Node push(Node head_ref, int data) { /* 1 & 2: Allocate the Node & Put in the data*/ Node new_node = new Node(data); /* 3. Make next of new Node as head */ new_node.down = head_ref; /* 4. Move the head to point to new Node */ head_ref = new_node; /*5. return to link it back */ return head_ref; } void printList() { Node temp = head; while (temp != null) { System.out.print(temp.data + " "); temp = temp.down; } System.out.println(); } /* Drier program to test above functions */ public static void main(String args[]) { LinkedList L = new LinkedList(); /* Let us create the following linked list 5 -> 10 -> 19 -> 28 | | | | V V V V 7 20 22 35 | | | V V V 8 50 40 | | V V 30 45 */ L.head = L.push(L.head, 30); L.head = L.push(L.head, 8); L.head = L.push(L.head, 7); L.head = L.push(L.head, 5); L.head.right = L.push(L.head.right, 20); L.head.right = L.push(L.head.right, 10); L.head.right.right = L.push(L.head.right.right, 50); L.head.right.right = L.push(L.head.right.right, 22); L.head.right.right = L.push(L.head.right.right, 19); L.head.right.right.right = L.push(L.head.right.right.right, 45); L.head.right.right.right = L.push(L.head.right.right.right, 40); L.head.right.right.right = L.push(L.head.right.right.right, 35); L.head.right.right.right = L.push(L.head.right.right.right, 20); // flatten the list L.head = L.flatten(L.head); L.printList(); } }
Delete a singly linked list node at a given position
Given a singly linked list and a position, delete a linked list node at the given position. Example: Input: position = 1, Linked List = 8->2->3->1->7 Output: Linked List = 8->3->1->7 Input: position = 0, Linked List = 8->2->3->1->7 Output: Linked List = 2->3->1->7 // A complete working Java program to delete a node in a linked list // at a given position class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node next; Node(int d) { data = d; next = null; } } /* Inserts a new Node at front of the list. */ public void push(int new_data) { /* 1 & 2: Allocate the Node & Put in the data*/ Node new_node = new Node(new_data); /* 3. Make next of new Node as head */ new_node.next = head; /* 4. Move the head to point to new Node */ head = new_node; } /* Given a reference (pointer to pointer) to the head of a list and a position, deletes the node at the given position */ void deleteNode(int position) { // If linked list is empty if (head == null) return; // Store head node Node temp = head; // If head needs to be removed if (position == 0) { head = temp.next; // Change head return; } // Find previous node of the node to be deleted for (int i=0; temp!=null && i<position-1; i++) temp = temp.next; // If position is more than number of ndoes if (temp == null || temp.next == null) return; // Node temp->next is the node to be deleted // Store pointer to the next of node to be deleted Node next = temp.next.next; temp.next = next; // Unlink the deleted node from list } /* This function prints contents of linked list starting from the given node */ public void printList() { Node tnode = head; while (tnode != null) { System.out.print(tnode.data+" "); tnode = tnode.next; } } /* Drier program to test above functions. Ideally this function should be in a separate user class. It is kept here to keep code compact */ public static void main(String[] args) { /* Start with the empty list */ LinkedList llist = new LinkedList(); llist.push(7); llist.push(1); llist.push(3); llist.push(2); llist.push(8); System.out.println("\nCreated Linked list is: "); llist.printList(); llist.deleteNode(4); // Delete node at position 4 System.out.println("\nLinked List after Deletion at position 4: "); llist.printList(); } }
Rotate a singly linked list
Given a singly linked list, rotate the linked list counter-clockwise by k nodes. Where k is a given positive integer. For example, if the given linked list is 10->20->30->40->50->60 and k is 4, the list should be modified to 50->60->10->20->30->40. Assume that k is smaller than the count of nodes in linked list. // Java program to rotate a linked list class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node next; Node(int d) { data = d; next = null; } } // This function rotates a linked list counter-clockwise // and updates the head. The function assumes that k is // smaller than size of linked list. It doesn't modify // the list if k is greater than or equal to size void rotate(int k) { if (k == 0) return; // Let us understand the below code for example k = 4 // and list = 10->20->30->40->50->60. Node current = head; // current will either point to kth or NULL after this // loop. current will point to node 40 in the above example int count = 1; while (count < k && current != null) { current = current.next; count++; } // If current is NULL, k is greater than or equal to count // of nodes in linked list. Don't change the list in this case if (current == null) return; // current points to kth node. Store it in a variable. // kthNode points to node 40 in the above example Node kthNode = current; // current will point to last node after this loop // current will point to node 60 in the above example while (current.next != null) current = current.next; // Change next of last node to previous head // Next of 60 is now changed to node 10 current.next = head; // Change head to (k+1)th node // head is now changed to node 50 head = kthNode.next; // change next of kth node to null kthNode.next = null; } /* Given a reference (pointer to pointer) to the head of a list and an int, push a new node on the front of the list. */ void push(int new_data) { /* 1 & 2: Allocate the Node & Put in the data*/ Node new_node = new Node(new_data); /* 3. Make next of new Node as head */ new_node.next = head; /* 4. Move the head to point to new Node */ head = new_node; } void printList() { Node temp = head; while(temp != null) { System.out.print(temp.data+" "); temp = temp.next; } System.out.println(); } /* Drier program to test above functions */ public static void main(String args[]) { LinkedList llist = new LinkedList(); // create a list 10->20->30->40->50->60 for (int i = 60; i >= 10; i -= 10) llist.push(i); System.out.println("Given list"); llist.printList(); llist.rotate(4); System.out.println("Rotated Linked List"); llist.printList(); } }
Sort a stack using recursion
Given a stack, sort it using recursion. Use of any loop constructs like while, for..etc is not allowed. We can only use the following ADT functions on Stack S: is_empty(S) : Tests whether stack is empty or not. push(S) : Adds new element to the stack. pop(S) : Removes top element from the stack. top(S) : Returns value of the top element. Note that this function does not remove element from the stack.
Check for balanced parentheses using stack
Given an expression string exp , write a program to examine whether the pairs and the orders of "{","}","(",")","[","]" are correct in exp. For example, the program should print true for exp = "[()]{}{[()()]()}" and false for exp = "[(])" Algorithm: 1) Declare a character stack S. 2) Now traverse the expression string exp. a) If the current character is a starting bracket ('(' or '{' or '[') then push it to stack. b) If the current character is a closing bracket (')' or '}' or ']') then pop from stack and if the popped character is the matching starting bracket then fine else parenthesis are not balanced. 3) After complete traversal, if there is some starting bracket left in stack then "not balanced" // Java program for checking // balanced Parenthesis public class BalancedParan { static class stack { int top=-1; char items[] = new char[100]; void push(char x) { if (top == 99) { System.out.println("Stack full"); } else { items[++top] = x; } } char pop() { if (top == -1) { System.out.println("Underflow error"); return '\0'; } else { char element = items[top]; top--; return element; } } boolean isEmpty() { return (top == -1) ? true : false; } } /* Returns true if character1 and character2 are matching left and right Parenthesis */ static boolean isMatchingPair(char character1, char character2) { if (character1 == '(' && character2 == ')') return true; else if (character1 == '{' && character2 == '}') return true; else if (character1 == '[' && character2 == ']') return true; else return false; } /* Return true if expression has balanced Parenthesis */ static boolean areParenthesisBalanced(char exp[]) { /* Declare an empty character stack */ stack st=new stack(); /* Traverse the given expression to check matching parenthesis */ for(int i=0;i<exp.length;i++) { /*If the exp[i] is a starting parenthesis then push it*/ if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[') st.push(exp[i]); /* If exp[i] is an ending parenthesis then pop from stack and check if the popped parenthesis is a matching pair*/ if (exp[i] == '}' || exp[i] == ')' || exp[i] == ']') { /* If we see an ending parenthesis without a pair then return false*/ if (st.isEmpty()) { return false; } /* Pop the top element from stack, if it is not a pair parenthesis of character then there is a mismatch. This happens for expressions like {(}) */ else if ( !isMatchingPair(st.pop(), exp[i]) ) { return false; } } } /* If there is something left in expression then there is a starting parenthesis without a closing parenthesis */ if (st.isEmpty()) return true; /*balanced*/ else { /*not balanced*/ return false; } } /* UTILITY FUNCTIONS */ /*driver program to test above functions*/ public static void main(String[] args) { char exp[] = {'{','(',')','}','[',']'}; if (areParenthesisBalanced(exp)) System.out.println("Balanced "); else System.out.println("Not Balanced "); } }
Reverse a singly linked list
Given pointer to the head node of a linked list, the task is to reverse the linked list. We need to reverse the list by changing links between nodes. Examples: Input : Head of following linked list 1->2->3->4->NULL Output : Linked list should be changed to, 4->3->2->1->NULL Input : Head of following linked list 1->2->3->4->5->NULL Output : Linked list should be changed to, 5->4->3->2->1->NULL Input : NULL Output : NULL Input : 1->NULL Output : 1->NULL // Java program for reversing the Linked list class LinkedList { static Node head; static class Node { int data; Node next; Node(int d) { data = d; next = null; } } // A simple and tail recursive function to reverse // a linked list. prev is passed as NULL initially. Node reverseUtil(Node curr, Node prev) { /* If last node mark it head*/ if (curr.next == null) { head = curr; /* Update next to prev node */ curr.next = prev; return null; } /* Save curr->next node for recursive call */ Node next1 = curr.next; /* and update next ..*/ curr.next = prev; reverseUtil(next1, curr); return head; } // prints content of double linked list void printList(Node node) { while (node != null) { System.out.print(node.data + " "); node = node.next; } } public static void main(String[] args) { LinkedList list = new LinkedList(); list.head = new Node(1); list.head.next = new Node(2); list.head.next.next = new Node(3); list.head.next.next.next = new Node(4); list.head.next.next.next.next = new Node(5); list.head.next.next.next.next.next = new Node(6); list.head.next.next.next.next.next.next = new Node(7); list.head.next.next.next.next.next.next.next = new Node(8); System.out.println("Original Linked list "); list.printList(head); Node res = list.reverseUtil(head, null); System.out.println(""); System.out.println(""); System.out.println("Reversed linked list "); list.printList(res); } }
Construct BST from given preorder traversal
Given preorder traversal of a binary search tree, construct the BST. For example, if the given traversal is {10, 5, 1, 7, 40, 50}, then the output should be root of following tree. 10 / \ 5 40 / \ \ 1 7 50 1. Create an empty stack. 2. Make the first value as root. Push it to the stack. 3. Keep on popping while the stack is not empty and the next value is greater than stack's top value. Make this value as the right child of the last popped node. Push the new node to the stack. 4. If the next value is less than the stack's top value, make this value as the left child of the stack's top node. Push the new node to the stack. 5. Repeat steps 2 and 3 until there are items remaining in pre[ ].
Reverse a stack using recursion
Write a program to reverse a stack using recursion. You are not allowed to use loop constructs like while, for..etc, and you can only use the following ADT functions on Stack S: isEmpty(S) push(S) pop(S)
The Celebrity Problem
In a party of N people, only one person is known to everyone. Such a person may be present in the party, if yes, (s)he doesn't know anyone in the party. We can only ask questions like "does A know B? ". Find the stranger (celebrity) in minimum number of questions. We can describe the problem input as an array of numbers/characters representing persons in the party. We also have a hypothetical function HaveAcquaintance(A, B) which returns true if A knows B, false otherwise. How can we solve the problem Method 3 (Using Stack) The graph construction takes O(N2) time, it is similar to brute force search. In case of recursion, we reduce the problem instance by not more than one, and also combine step may examine M-1 persons (M - instance size). We have following observation based on elimination technique (Refer Polya's How to Solve It book). If A knows B, then A can't be celebrity. Discard A, and B may be celebrity. If A doesn't know B, then B can't be celebrity. Discard B, and A may be celebrity. Repeat above two steps till we left with only one person. Ensure the remained person is celebrity. (Why do we need this step?) We can use stack to verity celebrity. Push all the celebrities into a stack. Pop off top two persons from the stack, discard one person based on return status of HaveAcquaintance(A, B). Push the remained person onto stack. Repeat step 2 and 3 until only one person remains in the stack. Check the remained person in stack doesn't have acquaintance with anyone else.
Stack Infix to Postfix
Infix expression:The expression of the form a op b. When an operator is in-between every pair of operands. Postfix expression:The expression of the form a b op. When an operator is followed for every pair of operands. Why postfix representation of the expression? The compiler scans the expression either from left to right or from right to left. Consider the below expression: a op1 b op2 c op3 d If op1 = +, op2 = *, op3 = + The compiler first scans the expression to evaluate the expression b * c, then again scan the expression to add a to it. The result is then added to d after another scan. The repeated scanning makes it very in-efficient. It is better to convert the expression to postfix(or prefix) form before evaluation. The corresponding expression in postfix form is: abc*+d+. The postfix expressions can be evaluated easily using a stack. We will cover postfix expression evaluation in a separate post. Algorithm 1. Scan the infix expression from left to right. 2. If the scanned character is an operand, output it. 3. Else, .....3.1 If the precedence of the scanned operator is greater than the precedence of the operator in the stack(or the stack is empty), push it. .....3.2 Else, Pop the operator from the stack until the precedence of the scanned operator is less-equal to the precedence of the operator residing on the top of the stack. Push the scanned operator to the stack. 4. If the scanned character is an '(', push it to the stack. 5. If the scanned character is an ')', pop and output from the stack until an '(' is encountered. 6. Repeat steps 2-6 until infix expression is scanned. 7. Pop and output from the stack until it is not empty. /* Java implementation to convert infix expression to postfix*/ // Note that here we use Stack class for Stack operations import java.util.Stack; class Test { // A utility function to return precedence of a given operator // Higher returned value means higher precedence static int Prec(char ch) { switch (ch) { case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; } return -1; } // The main method that converts given infix expression // to postfix expression. static String infixToPostfix(String exp) { // initializing empty String for result String result = new String(""); // initializing empty stack Stack<Character> stack = new Stack<>(); for (int i = 0; i<exp.length(); ++i) { char c = exp.charAt(i); // If the scanned character is an operand, add it to output. if (Character.isLetterOrDigit(c)) result += c; // If the scanned character is an '(', push it to the stack. else if (c == '(') stack.push(c); // If the scanned character is an ')', pop and output from the stack // until an '(' is encountered. else if (c == ')') { while (!stack.isEmpty() && stack.peek() != '(') result += stack.pop(); if (!stack.isEmpty() && stack.peek() != '(') return "Invalid Expression"; // invalid expression else stack.pop(); } else // an operator is encountered { while (!stack.isEmpty() && Prec(c) <= Prec(stack.peek())) result += stack.pop(); stack.push(c); } } // pop all the operators from the stack while (!stack.isEmpty()) result += stack.pop(); return result; } // Driver method public static void main(String[] args) { String exp = "a+b*(c^d-e)^(f+g*h)-i"; System.out.println(infixToPostfix(exp)); } }
Array Rotation (Juggling Algorithm)
Instead of moving one by one, divide the array in different sets where number of sets is equal to GCD of n and d and move the elements within sets. If GCD is 1 as is for the above example array (n = 7 and d =2), then elements will be moved within one set only, we just start with temp = arr[0] and keep moving arr[I+d] to arr[I] and finally store temp at the right place.
Queue
Like Stack, Queue is a linear structure which follows a particular order in which the operations are performed. The order is First In First Out (FIFO). A good example of queue is any queue of consumers for a resource where the consumer that came first is served first. The difference between stacks and queues is in removing. In a stack we remove the item the most recently added; in a queue, we remove the item the least recently added. Operations on Queue: Mainly the following four basic operations are performed on queue: Enqueue: Adds an item to the queue. If the queue is full, then it is said to be an Overflow condition. Dequeue: Removes an item from the queue. The items are popped in the same order in which they are pushed. If the queue is empty, then it is said to be an Underflow condition. Front: Get the front item from queue. Rear: Get the last item from queue. Applications of Queue: Queue is used when things don't have to be processed immediatly, but have to be processed in First InFirst Out order like Breadth First Search. This property of Queue makes it also useful in following kind of scenarios. 1) When a resource is shared among multiple consumers. Examples include CPU scheduling, Disk Scheduling. 2) When data is transferred asynchronously (data not necessarily received at same rate as sent) between two processes. Examples include IO Buffers, pipes, file IO, etc.
Priority Queue
Priority Queue is an extension of queue with following properties. 1) Every item has a priority associated with it. 2) An element with high priority is dequeued before an element with low priority. 3) If two elements have the same priority, they are served according to their order in the queue. A typical priority queue supports following operations. insert(item, priority): Inserts an item with given priority. getHighestPriority(): Returns the highest priority item. deleteHighestPriority(): Removes the highest priority item. Applications of Priority Queue: 1) CPU Scheduling 2) Graph algorithms like Dijkstra's shortest path algorithm, Prim's Minimum Spanning Tree, etc 3) All queue applications where priority is involved.
Reverse an array
Recursive Way: 1) Initialize start and end indexes start = 0, end = n-1 2) Swap arr[start] with arr[end] 3) Recursively call reverse for rest of the array.
Stack
Stack is a linear data structure which follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). Mainly the following three basic operations are performed in the stack: Push: Adds an item in the stack. If the stack is full, then it is said to be an Overflow condition. Pop: Removes an item from the stack. The items are popped in the reversed order in which they are pushed. If the stack is empty, then it is said to be an Underflow condition. Peek or Top: Returns top element of stack. isEmpty: Returns true if stack is empty, else false. How to understand a stack practically? There are many real life examples of stack. Consider the simple example of plates stacked over one another in canteen. The plate which is at the top is the first one to be removed, i.e. the plate which has been placed at the bottommost position remains in the stack for the longest period of time. So, it can be simply seen to follow LIFO/FILO order. Applications of stack: Balancing of symbols Infix to Postfix /Prefix conversion Redo-undo features at many places like editors, photoshop. Forward and backward feature in web browsers Used in many algorithms like Tower of Hanoi, tree traversals, stock span problem, histogram problem. Other applications can be Backtracking, Knight tour problem, rat in a maze, N queen problem and sudoku solver
Recursive Tower of Hanoi
Tower of Hanoi is a mathematical puzzle where we have three rods and n disks. The objective of the puzzle is to move the entire stack to another rod, obeying the following simple rules: 1) Only one disk can be moved at a time. 2) Each move consists of taking the upper disk from one of the stacks and placing it on top of another stack i.e. a disk can only be moved if it is the uppermost disk on a stack. 3) No disk may be placed on top of a smaller disk. // Java recursive program to solve tower of hanoi puzzle class GFG { // Java recursive function to solve tower of hanoi puzzle static void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod) { if (n == 1) { System.out.println("Move disk 1 from rod " + from_rod + " to rod " + to_rod); return; } towerOfHanoi(n-1, from_rod, aux_rod, to_rod); System.out.println("Move disk " + n + " from rod " + from_rod + " to rod " + to_rod); towerOfHanoi(n-1, aux_rod, to_rod, from_rod); } // Driver method public static void main(String args[]) { int n = 4; // Number of disks towerOfHanoi(n, 'A', 'C', 'B'); // A, B and C are names of rods } }
Binary Tree
Trees: Unlike Arrays, Linked Lists, Stack and queues, which are linear data structures, trees are hierarchical data structures. Tree Vocabulary: The topmost node is called root of the tree. The elements that are directly under an element are called its children. The element directly above something is called its parent. For example, a is a child of f and f is the parent of a. Finally, elements with no children are called leaves. Why Trees? 1. One reason to use trees might be because you want to store information that naturally forms a hierarchy. For example, the file system on a computer 2. Trees (with some ordering e.g., BST) provide moderate access/search (quicker than Linked List and slower than arrays). 3. Trees provide moderate insertion/deletion (quicker than Arrays and slower than Unordered Linked Lists). 4. Like Linked Lists and unlike Arrays, Trees don't have an upper limit on number of nodes as nodes are linked using pointers. Main applications of trees include: 1. Manipulate hierarchical data. 2. Make information easy to search (see tree traversal). 3. Manipulate sorted lists of data. 4. As a workflow for compositing digital images for visual effects. 5. Router algorithms 6. Form of a multi-stage decision-making (see business chess). Binary Tree: A tree whose elements have at most 2 children is called a binary tree. Since each element in a binary tree can have only 2 children, we typically name them the left and right child. Binary Tree Representation in C: A tree is represented by a pointer to the topmost node in tree. If the tree is empty, then value of root is NULL. A Tree node contains following parts. 1. Data 2. Pointer to left child 3. Pointer to right child
Move last element to front of a given linked list
Write a C function that moves last element to front in a given Singly Linked List. For example, if the given Linked List is 1->2->3->4->5, then the function should change the list to 5->1->2->3->4. Algorithm: Traverse the list till last node. Use two pointers: one to store the address of last node and other for address of second last node. After the end of loop do following operations. i) Make second last as last (secLast->next = NULL). ii) Set next of last as head (last->next = *head_ref). iii) Make last as head ( *head_ref = last) /* Java Program to move last element to front in a given linked list */ class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node next; Node(int d) {data = d; next = null; } } void moveToFront() { /* If linked list is empty or it contains only one node then simply return. */ if(head == null || head.next == null) return; /* Initialize second last and last pointers */ Node secLast = null; Node last = head; /* After this loop secLast contains address of second last node and last contains address of last node in Linked List */ while (last.next != null) { secLast = last; last = last.next; } /* Set the next of second last as null */ secLast.next = null; /* Set the next of last as head */ last.next = head; /* Change head to point to last node. */ head = last; } /* Utility functions */ /* Inserts a new Node at front of the list. */ public void push(int new_data) { /* 1 & 2: Allocate the Node & Put in the data*/ Node new_node = new Node(new_data); /* 3. Make next of new Node as head */ new_node.next = head; /* 4. Move the head to point to new Node */ head = new_node; } /* Function to print linked list */ void printList() { Node temp = head; while(temp != null) { System.out.print(temp.data+" "); temp = temp.next; } System.out.println(); } /* Drier program to test above functions */ public static void main(String args[]) { LinkedList llist = new LinkedList(); /* Constructed Linked List is 1->2->3->4->5->null */ llist.push(5); llist.push(4); llist.push(3); llist.push(2); llist.push(1); System.out.println("Linked List before moving last to front "); llist.printList(); llist.moveToFront(); System.out.println("Linked List after moving last to front "); llist.printList(); } }
Search an element in a singly linked list
Write a C function that searches a given key 'x' in a given singly linked list. The function should return true if x is present in linked list and false otherwise. bool search(Node *head, int x) For example, if the key to be searched is 15 and linked list is 14->21->11->30->10, then function should return false. If key to be searched is 14, then the function should return true. // Recursive Java program to search an element // in linked list // Node class class Node { int data; Node next; Node(int d) { data = d; next = null; } } // Linked list class class LinkedList { Node head; //Head of list //Inserts a new node at the front of the list public void push(int new_data) { //Allocate new node and putting data Node new_node = new Node(new_data); //Make next of new node as head new_node.next = head; //Move the head to point to new Node head = new_node; } // Checks whether the value x is present // in linked list public boolean search(Node head, int x) { // Base case if (head == null) return false; // If key is present in current node, // return true if (head.data == x) return true; // Recur for remaining list return search(head.next, x); } // Driver function to test the above functions public static void main(String args[]) { // Start with the empty list LinkedList llist = new LinkedList(); /* Use push() to construct below list 14->21->11->30->10 */ llist.push(10); llist.push(30); llist.push(11); llist.push(21); llist.push(14); if (llist.search(llist.head, 21)) System.out.println("Yes"); else System.out.println("No"); } }
Array Rotation
Write a function rotate(ar[], d, n) that rotates arr[] of size n by d elements.
Remove duplicates from a sorted singly linked list
Write a removeDuplicates() function which takes a list sorted in non-decreasing order and deletes any duplicate nodes from the list. The list should only be traversed once. For example if the linked list is 11->11->11->21->43->43->60 then removeDuplicates() should convert the list to 11->21->43->60. Algorithm: Traverse the list from the head (or start) node. While traversing, compare each node with its next node. If data of next node is same as current node then delete the next node. Before we delete a node, we need to store next pointer of the node Implementation: Functions other than removeDuplicates() are just to create a linked linked list and test removeDuplicates(). // Java program to remove duplicates from a sorted linked list class LinkedList { Node head; // head of list /* Linked list Node*/ class Node { int data; Node next; Node(int d) {data = d; next = null; } } void removeDuplicates() { /*Another reference to head*/ Node current = head; /* Pointer to store the next pointer of a node to be deleted*/ Node next_next; /* do nothing if the list is empty */ if (head == null) return; /* Traverse list till the last node */ while (current.next != null) { /*Compare current node with the next node */ if (current.data == current.next.data) { next_next = current.next.next; current.next = null; current.next = next_next; } else // advance if no deletion current = current.next; } } /* Utility functions */ /* Inserts a new Node at front of the list. */ public void push(int new_data) { /* 1 & 2: Allocate the Node & Put in the data*/ Node new_node = new Node(new_data); /* 3. Make next of new Node as head */ new_node.next = head; /* 4. Move the head to point to new Node */ head = new_node; } /* Function to print linked list */ void printList() { Node temp = head; while (temp != null) { System.out.print(temp.data+" "); temp = temp.next; } System.out.println(); } /* Drier program to test above functions */ public static void main(String args[]) { LinkedList llist = new LinkedList(); llist.push(20); llist.push(13); llist.push(13); llist.push(11); llist.push(11); llist.push(11); System.out.println("List before removal of duplicates"); llist.printList(); llist.removeDuplicates(); System.out.println("List after removal of elements"); llist.printList(); } }