Data Structure and Algorithm
Complied by Linh Truong | Incomplete
and will be updated
1 Data
Structure................................................................................................................................. 1
1.1 Hash Table................................................................................................................................ 3
1.2 Dynamic Array.......................................................................................................................... 7
1.3 Linked List............................................................................................................................... 11
1.4 Stacks..................................................................................................................................... 15
1.5 Queues................................................................................................................................... 15
1.6 Set.......................................................................................................................................... 15
1.7 TreeSet................................................................................................................................... 18
1.8 Binary Search Tree (BST).......................................................................................................... 20
1.9 Heap (Max Heap/Min Heap).................................................................................................... 25
1.10 Graph................................................................................................................................... 35
2 Algorithms..................................................................................................................................... 46
2.1 Sorting.................................................................................................................................... 48
2.2 Searching................................................................................................................................ 48
2.3 Tree Traversals........................................................................................................................ 48
2.4 Breadth-First Search................................................................................................................ 55
2.5 Depth-First Search................................................................................................................... 59
2.6 Binary Search.......................................................................................................................... 64
3 Concepts....................................................................................................................................... 66
3.1 Bit Manipulation..................................................................................................................... 66
3.2 Memory (Stack VS. Heap)........................................................................................................ 66
3.3 Recursion................................................................................................................................ 66
3.4 Dynamic Programming............................................................................................................ 66
3.5 Big 0 Time & Space.................................................................................................................. 66
Java Collection Framework cheat sheet
A collection is
a data structure—actually, an object—that can hold references to other objects.
Usually, collections contain references to objects that are all of the same
type. The collections-framework interfaces declare the operations to be
performed generically on various types of collections.
Interface |
Description |
Collection |
The root interface in the collections hierarchy from which
interfaces Set, Queue and List are derived. |
Set |
A collection that does not contain duplicates. |
List |
An ordered collection that can contain duplicate elements. |
Map |
A collection that associates keys to values and cannot contain
duplicate keys. |
Queue |
Typically a first-in, first-out collection that models a waiting
line; other orders can be specified. |
Hashtable was part of the original java.util and
is a concrete implementation of a Dictionary.
However, Java 2 re-engineered Hashtable so that
it also implements the Map interface. Thus, Hashtable is now integrated into
the collections framework. It is similar to HashMap, but is synchronized.
Like HashMap, Hashtable stores key/value pairs
in a hash table. When using a Hashtable, you specify an object that is used as
a key, and the value that you want linked to that key. The key is then hashed,
and the resulting hash code is used as the index at which the value is stored
within the table.
Following is the list of constructors provided
by the HashTable class.
Sr.No |
Constructor &
Description |
1 |
Hashtable( ) This is the default constructor of the hash table it
instantiates the Hashtable class. |
2 |
Hashtable(int size) This constructor accepts an integer parameter and creates a hash
table that has an initial size specified by integer value size. |
3 |
Hashtable(int size, float fillRatio) This creates a hash table that has an initial size specified by
size and a fill ratio specified by fillRatio. This ratio must be between 0.0
and 1.0, and it determines how full the hash table can be before it is
resized upward. |
4 |
Hashtable(Map < ? extends K, ? extends V > t) This constructs a Hashtable with the given mappings. |
Apart from the methods defined by Map interface,
Hashtable defines the following methods −
Sr.No |
Method &
Description |
1 |
void clear( ) Resets and empties the hash table. |
2 |
Object clone( ) Returns a duplicate of the invoking object. |
3 |
boolean contains(Object value) Returns true if some value equal to the value exists within the
hash table. Returns false if the value isn't found. |
4 |
boolean containsKey(Object key) Returns true if some key equal to the key exists within the hash
table. Returns false if the key isn't found. |
5 |
boolean containsValue(Object value) Returns true if some value equal to the value exists within the
hash table. Returns false if the value isn't found. |
6 |
Enumeration elements( ) Returns an enumeration of the values contained in the hash
table. |
7 |
Object get(Object key) Returns the object that contains the value associated with the
key. If the key is not in the hash table, a null object is returned. |
8 |
boolean isEmpty( ) Returns true if the hash table is empty; returns false if it
contains at least one key. |
9 |
Enumeration keys( ) Returns an enumeration of the keys contained in the hash table. |
10 |
Object put(Object key, Object value) Inserts a key and a value into the hash table. Returns null if
the key isn't already in the hash table; returns the previous value
associated with the key if the key is already in the hash table. |
11 |
void rehash( ) Increases the size of the hash table and rehashes all of its
keys. |
12 |
Object remove(Object key) Removes the key and its value. Returns the value associated with
the key. If the key is not in the hash table, a null object is returned. |
13 |
int size( ) Returns the number of entries in the hash table. |
14 |
String toString( ) Returns the string equivalent of a hash table. |
Example
The following program illustrates several of the
methods supported by this data structure −
import java.util.*;
public class HashTableDemo {
public static void main(String args[]) {
// Create a hash map
Hashtable balance = new Hashtable();
Enumeration names;
String str;
double bal;
balance.put("Zara", new Double(3434.34));
balance.put("Mahnaz", new Double(123.22));
balance.put("Ayan", new Double(1378.00));
balance.put("Daisy", new Double(99.22));
balance.put("Qadir", new Double(-19.08));
// Show all balances
in hash table.
names = balance.keys();
while(names.hasMoreElements()) {
str = (String) names.nextElement();
System.out.println(str + ": " + balance.get(str));
}
System.out.println();
// Deposit 1,000 into
Zara's account
bal = ((Double)balance.get("Zara")).doubleValue();
balance.put("Zara", new Double(bal + 1000));
System.out.println("Zara's new
balance: " + balance.get("Zara"));
}
}
This will produce the following result −
Output
Qadir: -19.08
Zara: 3434.34
Mahnaz: 123.22
Daisy: 99.22
Ayan: 1378.0
Zara's new balance: 4434.34
The ArrayList class extends AbstractList and
implements the List interface. ArrayList supports dynamic arrays that can grow
as needed.
Standard Java arrays are of a fixed length.
After arrays are created, they cannot grow or shrink, which means that you must
know in advance how many elements an array will hold.
Array lists are created with an initial size.
When this size is exceeded, the collection is automatically enlarged. When
objects are removed, the array may be shrunk.
Following is the list of the constructors
provided by the ArrayList class.
Sr.No. |
Constructor &
Description |
1 |
ArrayList( ) This constructor builds an empty array list. |
2 |
ArrayList(Collection c) This constructor builds an array list that is initialized with
the elements of the collection c. |
3 |
ArrayList(int capacity) This constructor builds an array list that has the specified
initial capacity. The capacity is the size of the underlying array that is
used to store the elements. The capacity grows automatically as elements are
added to an array list. |
Apart from the methods inherited from its parent
classes, ArrayList defines the following methods −
Sr.No. |
Method &
Description |
1 |
void add(int index, Object element) Inserts the specified element at the specified position index in
this list. Throws IndexOutOfBoundsException if the specified index is out of
range (index < 0 || index > size()). |
2 |
boolean add(Object o) Appends the specified element to the end of this list. |
3 |
boolean addAll(Collection c) Appends all of the elements in the specified collection to the
end of this list, in the order that they are returned by the specified
collection's iterator. Throws NullPointerException, if the specified collection
is null. |
4 |
boolean addAll(int index, Collection c) Inserts all of the elements in the specified collection into
this list, starting at the specified position. Throws NullPointerException if
the specified collection is null. |
5 |
void clear() Removes all of the elements from this list. |
6 |
Object clone() Returns a shallow copy of this ArrayList. |
7 |
boolean contains(Object o) Returns true if this list contains the specified element. More
formally, returns true if and only if this list contains at least one element
e such that (o==null ? e==null : o.equals(e)). |
8 |
void ensureCapacity(int minCapacity) Increases the capacity of this ArrayList instance, if necessary,
to ensure that it can hold at least the number of elements specified by the
minimum capacity argument. |
9 |
Object get(int index) Returns the element at the specified position in this list.
Throws IndexOutOfBoundsException if the specified index is out of range
(index < 0 || index >= size()). |
10 |
int indexOf(Object o) Returns the index in this list of the first occurrence of the
specified element, or -1 if the List does not contain this element. |
11 |
int lastIndexOf(Object o) Returns the index in this list of the last occurrence of the
specified element, or -1 if the list does not contain this element. |
12 |
Object remove(int index) Removes the element at the specified position in this list.
Throws IndexOutOfBoundsException if the index out is of range (index < 0
|| index >= size()). |
13 |
protected void removeRange(int fromIndex, int toIndex) Removes from this List all of the elements whose index is
between fromIndex, inclusive and toIndex, exclusive. |
14 |
Object set(int index, Object element) Replaces the element at the specified position in this list with
the specified element. Throws IndexOutOfBoundsException if the specified
index is out of range (index < 0 || index >= size()). |
15 |
int size() Returns the number of elements in this list. |
16 |
Object[] toArray() Returns an array containing all of the elements in this list in
the correct order. Throws NullPointerException if the specified array is
null. |
17 |
Object[] toArray(Object[] a) Returns an array containing all of the elements in this list in
the correct order; the runtime type of the returned array is that of the
specified array. |
18 |
void trimToSize() Trims the capacity of this ArrayList instance to be the list's
current size. |
Example
The following program illustrates several of the
methods supported by ArrayList −
import java.util.*;
public class ArrayListDemo {
public static void main(String args[]) {
// create an array list
ArrayList al = new ArrayList();
System.out.println("Initial size of
al: " + al.size());
// add elements to the
array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1, "A2");
System.out.println("Size of al after
additions: " + al.size());
// display the array
list
System.out.println("Contents of al:
" + al);
// Remove elements
from the array list
al.remove("F");
al.remove(2);
System.out.println("Size of al after
deletions: " + al.size());
System.out.println("Contents of al:
" + al);
}
}
This will produce the following result −
Output
Initial size of al: 0
Size of al after additions: 7
Contents of al: [C, A2, A, E, B, D, F]
Size of al after deletions: 5
Contents of al: [C, A2, E, B, D]
The LinkedList class extends AbstractSequentialList
and implements the List interface. It provides a linked-list data structure.
Following are the constructors supported by the
LinkedList class.
Sr.No. |
Constructor &
Description |
1 |
LinkedList( ) This constructor builds an empty linked list. |
2 |
LinkedList(Collection c) This constructor builds a linked list that is initialized with
the elements of the collection c. |
Apart from the methods inherited from its parent
classes, LinkedList defines following methods −
Sr.No. |
Method &
Description |
1 |
void add(int index, Object element) Inserts the specified element at the specified position index in
this list. Throws IndexOutOfBoundsException if the specified index is out of
range (index < 0 || index > size()). |
2 |
boolean add(Object o) Appends the specified element to the end of this list. |
3 |
boolean addAll(Collection c) Appends all of the elements in the specified collection to the
end of this list, in the order that they are returned by the specified
collection's iterator. Throws NullPointerException if the specified
collection is null. |
4 |
boolean addAll(int index, Collection c) Inserts all of the elements in the specified collection into
this list, starting at the specified position. Throws NullPointerException if
the specified collection is null. |
5 |
void addFirst(Object o) Inserts the given element at the beginning of this list. |
6 |
void addLast(Object o) Appends the given element to the end of this list. |
7 |
void clear() Removes all of the elements from this list. |
8 |
Object clone() Returns a shallow copy of this LinkedList. |
9 |
boolean contains(Object o) Returns true if this list contains the specified element. More
formally, returns true if and only if this list contains at least one element
e such that (o==null ? e==null : o.equals(e)). |
10 |
Object get(int index) Returns the element at the specified position in this list.
Throws IndexOutOfBoundsException if the specified index is out of range
(index < 0 || index >= size()). |
11 |
Object getFirst() Returns the first element in this list. Throws NoSuchElementException
if this list is empty. |
12 |
Object getLast() Returns the last element in this list. Throws
NoSuchElementException if this list is empty. |
13 |
int indexOf(Object o) Returns the index in this list of the first occurrence of the
specified element, or -1 if the list does not contain this element. |
14 |
int lastIndexOf(Object o) Returns the index in this list of the last occurrence of the
specified element, or -1 if the list does not contain this element. |
15 |
ListIterator listIterator(int index) Returns a list-iterator of the elements in this list (in proper
sequence), starting at the specified position in the list. Throws
IndexOutOfBoundsException if the specified index is out of range (index <
0 || index >= size()). |
16 |
Object remove(int index) Removes the element at the specified position in this list.
Throws NoSuchElementException if this list is empty. |
17 |
boolean remove(Object o) Removes the first occurrence of the specified element in this
list. Throws NoSuchElementException if this list is empty. Throws
IndexOutOfBoundsException if the specified index is out of range (index <
0 || index >= size()). |
18 |
Object removeFirst() Removes and returns the first element from this list. Throws
NoSuchElementException if this list is empty. |
19 |
Object removeLast() Removes and returns the last element from this list. Throws
NoSuchElementException if this list is empty. |
20 |
Object set(int index, Object element) Replaces the element at the specified position in this list with
the specified element. Throws IndexOutOfBoundsException if the specified
index is out of range (index < 0 || index >= size()). |
21 |
int size() Returns the number of elements in this list. |
22 |
Object[] toArray() Returns an array containing all of the elements in this list in
the correct order. Throws NullPointerException if the specified array is
null. |
23 |
Object[] toArray(Object[] a) Returns an array containing all of the elements in this list in
the correct order; the runtime type of the returned array is that of the
specified array. |
Example
The following program illustrates several of the
methods supported by LinkedList −
import java.util.*;
public class LinkedListDemo {
public static void main(String args[]) {
// create a linked
list
LinkedList ll = new LinkedList();
// add elements to the
linked list
ll.add("F");
ll.add("B");
ll.add("D");
ll.add("E");
ll.add("C");
ll.addLast("Z");
ll.addFirst("A");
ll.add(1, "A2");
System.out.println("Original
contents of ll: " + ll);
// remove elements
from the linked list
ll.remove("F");
ll.remove(2);
System.out.println("Contents of ll
after deletion: " + ll);
// remove first and
last elements
ll.removeFirst();
ll.removeLast();
System.out.println("ll after
deleting first and last: " + ll);
// get and set a value
Object val = ll.get(2);
ll.set(2, (String) val + " Changed");
System.out.println("ll after change:
" + ll);
}
}
This will produce the following result −
Output
Original contents of ll: [A, A2, F, B, D, E, C,
Z]
Contents of ll after deletion: [A, A2, D, E, C,
Z]
ll after deleting first and last: [A2, D, E, C]
ll after change: [A2, D, E Changed, C]
A Set is a Collection that cannot contain
duplicate elements. It models the mathematical set abstraction.
The Set interface contains only methods
inherited from Collection and adds the restriction that duplicate elements are
prohibited.
Set also adds a stronger contract on the
behavior of the equals and hashCode operations, allowing Set instances to be
compared meaningfully even if their implementation types differ.
The methods declared by Set are summarized in
the following table −
Sr.No. |
Method &
Description |
1 |
add( ) Adds an object to the collection. |
2 |
clear( ) Removes all objects from the collection. |
3 |
contains( ) Returns true if a specified object is an element within the collection. |
4 |
isEmpty( ) Returns true if the collection has no elements. |
5 |
iterator( ) Returns an Iterator object for the collection, which may be used
to retrieve an object. |
6 |
remove( ) Removes a specified object from the collection. |
7 |
size( ) Returns the number of elements in the collection. |
Example
Set has its implementation in various classes
like HashSet, TreeSet, LinkedHashSet. Following is an example to explain Set
functionality −
import java.util.*;
public class SetDemo {
public static void main(String args[]) {
int count[] = {34, 22,10,60,30,22};
Set<Integer> set = new HashSet<Integer>();
try {
for(int i = 0; i < 5; i++) {
set.add(count[i]);
}
System.out.println(set);
TreeSet sortedSet = new TreeSet<Integer>(set);
System.out.println("The sorted list
is:");
System.out.println(sortedSet);
System.out.println("The First
element of the set is: "+ (Integer)sortedSet.first());
System.out.println("The last element
of the set is: "+ (Integer)sortedSet.last());
}
catch(Exception e) {}
}
}
This will produce the following result −
Output
[34, 22, 10, 60, 30]
The sorted list is:
[10, 22, 30, 34, 60]
The First element of the set is: 10
The last element of the set is: 60
TreeSet provides an implementation of the Set
interface that uses a tree for storage. Objects are stored in a sorted and
ascending order.
Access and retrieval times are quite fast, which
makes TreeSet an excellent choice when storing large amounts of sorted
information that must be found quickly.
Following is the list of the constructors
supported by the TreeSet class.
Sr.No. |
Constructor &
Description |
1 |
TreeSet( ) This constructor constructs an empty tree set that will be
sorted in an ascending order according to the natural order of its elements. |
2 |
TreeSet(Collection c) This constructor builds a tree set that contains the elements of
the collection c. |
3 |
TreeSet(Comparator comp) This constructor constructs an empty tree set that will be
sorted according to the given comparator. |
4 |
TreeSet(SortedSet ss) This constructor builds a TreeSet that contains the elements of
the given SortedSet. |
Apart from the methods inherited from its parent
classes, TreeSet defines the following methods −
Sr.No. |
Method &
Description |
1 |
void add(Object o) Adds the specified element to this set if it is not already
present. |
2 |
boolean addAll(Collection c) Adds all of the elements in the specified collection to this
set. |
3 |
void clear() Removes all of the elements from this set. |
4 |
Object clone() Returns a shallow copy of this TreeSet instance. |
5 |
Comparator comparator() Returns the comparator used to order this sorted set, or null if
this tree set uses its elements natural ordering. |
6 |
boolean contains(Object o) Returns true if this set contains the specified element. |
7 |
Object first() Returns the first (lowest) element currently in this sorted set. |
8 |
SortedSet headSet(Object toElement) Returns a view of the portion of this set whose elements are
strictly less than toElement. |
9 |
boolean isEmpty() Returns true if this set contains no elements. |
10 |
Iterator iterator() Returns an iterator over the elements in this set. |
11 |
Object last() Returns the last (highest) element currently in this sorted set. |
12 |
boolean remove(Object o) Removes the specified element from this set if it is present. |
13 |
int size() Returns the number of elements in this set (its cardinality). |
14 |
SortedSet subSet(Object fromElement, Object toElement) Returns a view of the portion of this set whose elements range
from fromElement, inclusive, to toElement, exclusive. |
15 |
SortedSet tailSet(Object fromElement) Returns a view of the portion of this set whose elements are
greater than or equal to fromElement. |
Example
The following program illustrates several of the
methods supported by this collection −
import java.util.*;
public class TreeSetDemo {
public static void main(String args[]) {
// Create a tree set
TreeSet ts = new TreeSet();
// Add elements to the
tree set
ts.add("C");
ts.add("A");
ts.add("B");
ts.add("E");
ts.add("F");
ts.add("D");
System.out.println(ts);
}
}
This will produce the following result −
Output
[A, B, C, D, E, F]
A Binary Search Tree (BST) is a tree in which all the
nodes follow the below-mentioned properties −
·
The left sub-tree of a node has a key less than or equal to its
parent node's key.
·
The right sub-tree of a node has a key greater than to its parent
node's key.
Thus, BST divides all its sub-trees into two segments;
the left sub-tree and the right sub-tree and can be defined as −
left_subtree (keys)
≤ node (key) ≤
right_subtree (keys)
Basic Operations
Following are the basic operations of a tree −
·
Search − Searches an element in a
tree.
·
Insert − Inserts an element in a
tree.
·
Pre-order Traversal − Traverses a tree in a
pre-order manner.
·
In-order Traversal − Traverses a tree in an
in-order manner.
·
Post-order Traversal − Traverses a tree in a
post-order manner.
Node
Define a node having some data, references to its left
and right child nodes.
struct node {
int data;
struct node *leftChild;
struct node *rightChild;
};
Search Operation
Whenever an element is to be searched, start searching
from the root node. Then if the data is less than the key value, search for the
element in the left subtree. Otherwise, search for the element in the right
subtree. Follow the same algorithm for each node.
Algorithm
struct node* search(int data){
struct node *current = root;
printf("Visiting elements: ");
while(current->data != data){
if(current != NULL) {
printf("%d ",current->data);
//go to left tree
if(current->data > data){
current = current->leftChild;
} //else go to right tree
else {
current = current->rightChild;
}
//not found
if(current == NULL){
return NULL;
}
}
}
return current;
}
Insert Operation
Whenever an element is to be inserted, first locate its
proper location. Start searching from the root node, then if the data is less
than the key value, search for the empty location in the left subtree and
insert the data. Otherwise, search for the empty location in the right subtree
and insert the data.
Algorithm
void insert(int data) {
struct node *tempNode = (struct node*) malloc(sizeof(struct node));
struct node *current;
struct node *parent;
tempNode->data = data;
tempNode->leftChild = NULL;
tempNode->rightChild = NULL;
//if tree is empty
if(root == NULL) {
root = tempNode;
} else {
current = root;
parent = NULL;
while(1) {
parent = current;
//go to left of the tree
if(data < parent->data) {
current = current->leftChild;
//insert to the
left
if(current == NULL) {
parent->leftChild = tempNode;
return;
}
} //go to right of the tree
else {
current = current->rightChild;
//insert to the
right
if(current == NULL) {
parent->rightChild = tempNode;
return;
}
}
}
}
}
Heap represents a special tree based data structure
used to represent priority queue or for heap sort. We'll going to discuss
binary heap tree specifically.
Binary heap tree can be classified as a binary tree
with two constraints:
·
Completeness - Binary heap tree is a complete
binary tree except the last level which may not have all elements but elements
from left to right should be filled in.
·
Heapness - All parent nodes should be
greater or smaller to their children. If parent node is to be greater than its
child then it is called Max heap otherwise it is called Min heap. Max heap is
used for heap sort and Min heap is used for priority queue. We're considering
Min Heap and will use array implementation for the same.
Basic Operations
Following are basic primary operations of a Min heap
which are following.
·
Insert - insert an element in a heap.
·
Get Minimum - get minimum element from the heap.
·
Remove Minimum - remove the minimum element from
the heap
Insert Operation
·
Whenever an element is to be inserted. Insert element at the end
of the array. Increase the size of heap by 1.
·
Heap up the element while heap property is broken. Compare element
with parent's value and swap them if required.
void insert(int value) {
size++;
intArray[size - 1] = value;
heapUp(size - 1);
}
void heapUp(int nodeIndex){
int parentIndex, tmp;
if (nodeIndex != 0) {
parentIndex = getParentIndex(nodeIndex);
if (intArray[parentIndex] > intArray[nodeIndex]) {
tmp = intArray[parentIndex];
intArray[parentIndex] = intArray[nodeIndex];
intArray[nodeIndex] = tmp;
heapUp(parentIndex);
}
}
}
Get Minimum
Get the first element of the array implementing the
heap being root.
int getMinimum(){
return intArray[0];
}
Remove Minimum
·
Whenever an element is to be removed. Get the last element of the
array and reduce size of heap by 1.
·
Heap down the element while heap property is broken. Compare
element with children's value and swap them if required.
void removeMin() {
intArray[0] = intArray[size - 1];
size--;
if (size > 0)
heapDown(0);
}
void heapDown(int nodeIndex){
int leftChildIndex, rightChildIndex, minIndex, tmp;
leftChildIndex = getLeftChildIndex(nodeIndex);
rightChildIndex =
getRightChildIndex(nodeIndex);
if (rightChildIndex >= size) {
if (leftChildIndex >= size)
return;
else
minIndex = leftChildIndex;
} else {
if (intArray[leftChildIndex] <= intArray[rightChildIndex])
minIndex = leftChildIndex;
else
minIndex = rightChildIndex;
}
if (intArray[nodeIndex] > intArray[minIndex]) {
tmp = intArray[minIndex];
intArray[minIndex] = intArray[nodeIndex];
intArray[nodeIndex] = tmp;
heapDown(minIndex);
}
}
Demo Program
HeapDemo.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int intArray[10];
int size;
bool isEmpty(){
return size == 0;
}
int getMinimum(){
return intArray[0];
}
int
getLeftChildIndex(int nodeIndex){
return 2*nodeIndex +1;
}
int
getRightChildIndex(int nodeIndex){
return 2*nodeIndex +2;
}
int getParentIndex(int nodeIndex){
return (nodeIndex -1)/2;
}
bool isFull(){
return size == 10;
}
/**
* Heap up the new element,until
heap property is broken.
* Steps:
* 1. Compare node's value with
parent's value.
* 2. Swap them, If they are in
wrong order.
* */
void heapUp(int nodeIndex){
int parentIndex, tmp;
if (nodeIndex != 0) {
parentIndex = getParentIndex(nodeIndex);
if (intArray[parentIndex] > intArray[nodeIndex]) {
tmp = intArray[parentIndex];
intArray[parentIndex] = intArray[nodeIndex];
intArray[nodeIndex] = tmp;
heapUp(parentIndex);
}
}
}
/**
* Heap down the root element
being least in value,until heap property is broken.
* Steps:
* 1.If current node has no
children, done.
* 2.If current node has one
children and heap property is broken,
* 3.Swap the current node and
child node and heap down.
* 4.If current node has one
children and heap property is broken, find smaller one
* 5.Swap the current node and
child node and heap down.
* */
void heapDown(int nodeIndex){
int leftChildIndex, rightChildIndex, minIndex, tmp;
leftChildIndex = getLeftChildIndex(nodeIndex);
rightChildIndex =
getRightChildIndex(nodeIndex);
if (rightChildIndex >= size) {
if (leftChildIndex >= size)
return;
else
minIndex = leftChildIndex;
} else {
if (intArray[leftChildIndex] <= intArray[rightChildIndex])
minIndex = leftChildIndex;
else
minIndex = rightChildIndex;
}
if (intArray[nodeIndex] > intArray[minIndex]) {
tmp = intArray[minIndex];
intArray[minIndex] = intArray[nodeIndex];
intArray[nodeIndex] = tmp;
heapDown(minIndex);
}
}
void insert(int value) {
size++;
intArray[size - 1] = value;
heapUp(size - 1);
}
void removeMin() {
intArray[0] = intArray[size - 1];
size--;
if (size > 0)
heapDown(0);
}
main()
{
/*
5 //Level 0
*
*/
insert(5);
/*
1 //Level 0
* |
* 5---| //Level 1
*/
insert(1);
/*
1 //Level 0
* |
* 5---|---3 //Level 1
*/
insert(3);
/*
1 //Level 0
* |
* 5---|---3 //Level 1
* |
* 8--| //Level 2
*/
insert(8);
/*
1 //Level 0
* |
* 5---|---3 //Level 1
* |
* 8--|--9 //Level 2
*/
insert(9);
/*
1 //Level 0
* |
* 5---|---3 //Level 1
* | |
* 8--|--9 6--| //Level 2
*/
insert(6);
/*
1 //Level 0
* |
* 5---|---2 //Level 1
* | |
* 8--|--9 6--|--3 //Level 2
*/
insert(2);
printf("%d", getMinimum());
removeMin();
/*
2 //Level 0
* |
* 5---|---3 //Level 1
* | |
* 8--|--9 6--| //Level 2
*/
printf("\n%d", getMinimum());
}
If we compile and run the above program then it would
produce following result:
1
2
A graph is an abstract notation used to represent the
connection between pairs of objects. A graph consists of −
·
Vertices − Interconnected objects in
a graph are called vertices. Vertices are also known as nodes.
·
Edges − Edges are the links that
connect the vertices.
There are two types of graphs −
·
Directed graph − In a directed graph, edges
have direction, i.e., edges go from one vertex to another.
·
Undirected graph − In an undirected graph,
edges have no direction.
Graph Coloring
Graph coloring is a method to assign colors to the
vertices of a graph so that no two adjacent vertices have the same color. Some
graph coloring problems are −
·
Vertex coloring − A way of coloring the
vertices of a graph so that no two adjacent vertices share the same color.
·
Edge Coloring − It is the method of
assigning a color to each edge so that no two adjacent edges have the same
color.
·
Face coloring − It assigns a color to each
face or region of a planar graph so that no two faces that share a common
boundary have the same color.
Chromatic Number
Chromatic number is the minimum number of colors
required to color a graph. For example, the chromatic number of the following
graph is 3.
The concept of graph coloring is applied in preparing
timetables, mobile radio frequency assignment, Suduku, register allocation, and
coloring of maps.
Steps for graph coloring
·
Set the initial value of each processor in the n-dimensional array
to 1.
·
Now to assign a particular color to a vertex, determine whether
that color is already assigned to the adjacent vertices or not.
·
If a processor detects same color in the adjacent vertices, it
sets its value in the array to 0.
·
After making n2 comparisons, if any element of the array is 1, then it is a valid
coloring.
Pseudocode for graph coloring
begin
create the processors P(i0,i1,...in-1) where 0_iv < m, 0 _ v < n
status[i0,..in-1] = 1
for j varies from 0 to n-1 do
begin
for k varies from 0 to n-1 do
begin
if aj,k=1 and ij=ikthen
status[i0,..in-1] =0
end
end
ok = ΣStatus
if ok > 0, then display valid coloring exists
else
display invalid coloring
end
Minimal Spanning Tree
A spanning tree whose sum of weight (or length) of all
its edges is less than all other possible spanning tree of graph G is known as
a minimal spanning tree or minimum cost spanning tree.
To implement the minimum cost-spanning tree, the
following two methods are used −
·
Prim’s Algorithm
·
Kruskal’s Algorithm
Prim's Algorithm
Prim’s algorithm is a greedy algorithm, which helps us
find the minimum spanning tree for a weighted undirected graph. It selects a
vertex first and finds an edge with the lowest weight incident on that vertex.
Steps of Prim’s Algorithm
·
Select any vertex, say v1 of Graph G.
·
Select an edge, say e1 of G such that e1 = v1 v2 and v1 ≠ v2 and e1 has minimum weight among the edges incident on v1 in graph G.
·
Now, following step 2, select the minimum weighted edge incident
on v2.
·
Continue this till n–1 edges have been chosen. Here n is the number of vertices. Kruskal's Algorithm
Kruskal’s algorithm is a greedy algorithm, which helps
us find the minimum spanning tree for a connected weighted graph, adding
increasing cost arcs at each step. It is a minimum-spanning-tree algorithm that
finds an edge of the least possible weight that connects any two trees in the
forest.
Steps of Kruskal’s Algorithm
·
Select an edge of minimum weight; say e1 of Graph G and e1 is not a loop.
·
Select the next minimum weighted edge connected to e1.
·
Continue this till n–1 edges have been chosen. Here n is the number of vertices. Shortest Path Algorithm
Shortest Path algorithm is a method of finding the
least cost path from the source node(S) to the destination node (D). Here, we
will discuss Moore’s algorithm, also known as Breadth First Search Algorithm.
Moore’s algorithm
·
Label the source vertex, S and label it i and set i=0.
·
Find all unlabeled vertices adjacent to the vertex labeled i. If no vertices are connected to the
vertex, S, then vertex, D, is not connected to S. If there are vertices
connected to S, label them i+1.
·
If D is labeled, then go to step 4, else go to step 2 to increase
i=i+1.
·
Stop after the length of the shortest path is found.
In this section we will see different traversal
algorithms to traverse keys present in binary search tree. These traversals are
Inorder traversal, Preorder traversal, Postorder traversal and the level order
traversal.
Suppose we have one tree like this −
The Inorder traversal sequence will be like
− 5 8 10 15 16 20 23
The Preorder traversal sequence will be like
− 10 5 8 16 15 20 23
The Postorder traversal sequence will be like
− 8 5 15 23 20 16 10
The Level-order traversal sequence will be like
− 10, 5, 16, 8, 15, 20, 23
Algorithm
inorderTraverse(root):
Begin
if root is not empty, then
inorderTraversal(left of root)
print the value of root
inorderTraversal(right of root)
end if
End
preorderTraverse(root):
Begin
if root is not empty, then
print the value of root
preorderTraversal(left of root)
preorderTraversal(right of root)
end if
End
postorderTraverse(root):
Begin
if root is not empty, then
postorderTraversal(left of root)
postorderTraversal(right of root)
print the value of root
end if
End
levelOrderTraverse(root):
Begin
define queue que to store nodes
insert root into the que.
while que is not empty, do
item := item present at front position of
queue
print the value of item
if left of the item is not null, then
insert left of item into que
end if
if right of the item is not null, then
insert right of item into que
end if
delete front element from que
done
End
Example
#include<iostream>
#include<queue>
using namespace std;
class node{
public:
int h_left, h_right, bf, value;
node *left, *right;
};
class tree{
private:
node *get_node(int key);
public:
node *root;
tree(){
root = NULL; //set root as NULL at the beginning
}
void inorder_traversal(node *r);
void preorder_traversal(node *r);
void postorder_traversal(node *r);
void levelorder_traversal(node *r);
node *insert_node(node *root, int key);
};
node *tree::get_node(int key){
node *new_node;
new_node = new node; //create a new node
dynamically
new_node->h_left = 0; new_node->h_right = 0;
new_node->bf = 0;
new_node->value = key; //store the value from given key
new_node->left = NULL; new_node->right = NULL;
return new_node;
}
void tree::inorder_traversal(node *r){
if(r != NULL){ //When root is present, visit left - root - right
inorder_traversal(r->left);
cout << r->value << " ";
inorder_traversal(r->right);
}
}
void tree::preorder_traversal(node *r){
if(r != NULL){ //When root is present, visit left - root - right
cout << r->value << " ";
preorder_traversal(r->left);
preorder_traversal(r->right);
}
}
void tree::postorder_traversal(node *r){
if(r != NULL){ //When root is present, visit left - root - right
postorder_traversal(r->left);
postorder_traversal(r->right);
cout << r->value << " ";
}
}
void tree::levelorder_traversal(node *root){
queue <node*> que;
node *item;
que.push(root); //insert the root at
first
while(!que.empty()){
item = que.front(); //get the element from
the front end
cout << item->value << " ";
if(item->left != NULL) //When left child is present,
insert into queue
que.push(item->left);
if(item->right != NULL) //When right child is
present, insert into queue
que.push(item->right);
que.pop(); //remove the item from queue
}
}
node *tree::insert_node(node *root, int key){
if(root == NULL){
return (get_node(key)); //when tree is empty, create a node as root
}
if(key < root->value){ //when key is smaller
than root value, go to the left
root->left = insert_node(root->left, key);
}else if(key > root->value){ //when key is greater
than root value, go to the right
root->right = insert_node(root->right, key);
}
return root; //when key is already present, do not insert it again
}
main(){
node *root;
tree my_tree;
//Insert some keys
into the tree.
my_tree.root = my_tree.insert_node(my_tree.root, 10);
my_tree.root = my_tree.insert_node(my_tree.root, 5);
my_tree.root = my_tree.insert_node(my_tree.root, 16);
my_tree.root = my_tree.insert_node(my_tree.root, 20);
my_tree.root = my_tree.insert_node(my_tree.root, 15);
my_tree.root = my_tree.insert_node(my_tree.root, 8);
my_tree.root = my_tree.insert_node(my_tree.root, 23);
cout << "In-Order Traversal: ";
my_tree.inorder_traversal(my_tree.root);
cout << "\nPre-Order Traversal: ";
my_tree.preorder_traversal(my_tree.root);
cout << "\nPost-Order Traversal: ";
my_tree.postorder_traversal(my_tree.root);
cout << "\nLevel-Order Traversal: ";
my_tree.levelorder_traversal(my_tree.root);
}
Output
In-Order Traversal: 5 8 10 15 16 20 23
Pre-Order Traversal: 10
5 8 16 15 20 23
Post-Order Traversal: 8
5 15 23 20 16 10
Level-Order Traversal: 10 5 16 8 15 20 23
Breadth First Search or BFS for a Graph
The Breadth First Search (BFS) traversal is an
algorithm, which is used to visit all of the nodes of a given graph. In this
traversal algorithm one node is selected and then all of the adjacent nodes are
visited one by one. After completing all of the adjacent vertices, it moves
further to check another vertices and checks its adjacent vertices again.
To implement this algorithm, we need to use the
Queue data structure. All the adjacent vertices are added into the queue, when
all adjacent vertices are completed, one item is removed from the queue and
start traversing through that vertex again.
In Graph sometimes, we may get some cycles, so
we will use an array to mark when a node is visited already or not.
Input - The Adjacency matrix
of the graph.
A B C D E F
A 0 1 1 1 0 0
B 1 0 0 1 1 0
C 1 0 0 1 0 1
D 1 1 1 0 1 1
E 0 1 0 1 0 1
F 0 0 1 1 1 0
Output - BFS Traversal: B A D
E C F
Algorithm
bfs(vertices, start)
Input − The list of
vertices, and the start vertex.
Output − Traverse all of
the nodes, if the graph is connected.
Begin
define an empty queue que
at first mark all nodes status as unvisited
add the start vertex into the que
while que is not empty, do
delete item from que and set to u
display the vertex u
for all vertices 1 adjacent with u, do
if vertices[i] is unvisited, then
mark vertices[i] as temporarily
visited
add v into the queue
mark
done
mark u as completely visited
done
End
Example
#include<iostream>
#include<queue>
#define NODE 6
using namespace std;
typedef struct node{
int val;
int state; //status
}node;
int graph[NODE][NODE] = {
{0, 1, 1, 1, 0, 0},
{1, 0, 0, 1, 1, 0},
{1, 0, 0, 1, 0, 1},
{1, 1, 1, 0, 1, 1},
{0, 1, 0, 1, 0, 1},
{0, 0, 1, 1, 1, 0}
};
void bfs(node *vert, node s){
node u;
int i, j;
queue<node> que;
for(i = 0; i<NODE; i++){
vert[i].state = 0; //not visited
}
vert[s.val].state = 1;//visited
que.push(s); //insert starting node
while(!que.empty()){
u = que.front(); //delete from queue
and print
que.pop();
cout << char(u.val+'A') << " ";
for(i = 0; i<NODE; i++){
if(graph[i][u.val]){
//when
the node is non-visited
if(vert[i].state == 0){
vert[i].state = 1;
que.push(vert[i]);
}
}
}
u.state = 2;//completed for node u
}
}
int main(){
node vertices[NODE];
node start;
char s;
for(int i = 0; i<NODE; i++){
vertices[i].val = i;
}
s = 'B';//starting vertex B
start.val = s-'A';
cout << "BFS Traversal: ";
bfs(vertices, start);
cout << endl;
}
Output
BFS Traversal: B A D E C F
Depth First Search or DFS for a Graph
The Depth First Search (DFS) is a graph
traversal algorithm. In this algorithm one starting vertex is given, and when
an adjacent vertex is found, it moves to that adjacent vertex first and try to
traverse in the same manner.
It moves through the whole depth, as much as it
can go, after that it backtracks to reach previous vertices to find new path.
To implement DFS in iterative way, we need to
use the stack data structure. If we want to do it recursively, external stacks
are not needed, it can be done internal stacks for the recursion calls.
Input: The Adjacency matrix
of a graph.
A B C D E F
A 0 1 1 1 0 0
B 1 0 0 1 1 0
C 1 0 0 1 0 1
D 1 1 1 0 1 1
E 0 1 0 1 0 1
F 0 0 1 1 1 0
Output: DFS Traversal: C F E B
D A
Algorithm
dfs(vertices, start)
Input − The list of all
vertices, and the start node.
Output − Traverse all
nodes in the graph.
Begin
initially make the state to unvisited for
all nodes
push start into the stack
while stack is not empty, do
pop element from stack and set to u
display the node u
if u is not visited, then
mark u as visited
for all nodes i connected to u, do
if ith vertex is unvisited, then
push ith vertex into the stack
mark ith vertex as visited
done
done
End
Example
#include<iostream>
#include<stack>
using namespace std;
#define NODE 6
typedef struct node{
int val;
int state; //status
}node;
int graph[NODE][NODE] = {
{0, 1, 1, 1, 0, 0},
{1, 0, 0, 1, 1, 0},
{1, 0, 0, 1, 0, 1},
{1, 1, 1, 0, 1, 1},
{0, 1, 0, 1, 0, 1},
{0, 0, 1, 1, 1, 0}
};
void dfs(node *vertex, node start){
node u;
stack<node> myStack;
for(int i = 0; i<NODE; i++){
vertex[i].state = 0;//not visited
}
myStack.push(start);
while(!myStack.empty()){
//pop and print node
u = myStack.top();
myStack.pop();
cout << char(u.val+'A') << " ";
if(u.state != 1){
//update vertex status to visited
u.state = 1;
vertex[u.val].state = 1;
for(int i = 0; i<NODE; i++){
if(graph[i][u.val]){
if(vertex[i].state == 0){
myStack.push(vertex[i]);
vertex[i].state = 1;
}
}
}
}
}
}
int main(){
node vertices[NODE];
node start;
char s;
for(int i = 0; i<NODE; i++){
vertices[i].val = i;
}
s = 'C';//starting vertex C
start.val = s-'A';
cout << "DFS Traversal: ";
dfs(vertices, start);
cout << endl;
}
Output
DFS Traversal: C F E B D A
Description
The java.util.Arrays.binarySearch(int[]
a, int key) method searches the specified array of ints for the specified
value using the binary search algorithm.The array must be sorted before making
this call.If it is not sorted, the results are undefined.
Declaration
Following is the declaration for java.util.Arrays.binarySearch() method
public static int binarySearch(int[] a, int key)
Parameters
·
a − This is the array to be searched.
·
key − This is the value to be
searched for.
Return Value
This method returns index of the search key, if it is
contained in the array, else it returns (-(insertion point) - 1). The insertion
point is the point at which the key would be inserted into the array: the index
of the first element greater than the key, or a.length if all elements in the
array are less than the specified key.
Exception
NA
Example
The following example shows the usage of
java.util.Arrays.binarySearch() method.
package com.tutorialspoint;
import java.util.Arrays;
public class ArrayDemo {
public static void main(String[] args) {
// initializing unsorted int
array
int intArr[] = {30,20,5,12,55};
// sorting array
Arrays.sort(intArr);
// let us print all the elements
available in list
System.out.println("The sorted int array is:");
for (int number : intArr) {
System.out.println("Number = " + number);
}
// entering the value to be
searched
int searchVal = 12;
int retVal = Arrays.binarySearch(intArr,searchVal);
System.out.println("The index of element 12 is : " + retVal);
}
}
Let us compile and run the above program, this will
produce the following result −
The sorted int array is:
Number = 5
Number = 12
Number = 20
Number = 30
Number = 55
The index of element 12 is : 1