Linked List
Linked list is a linear data structure. It uses pointers to access data so that its memory is un-continunious.
Advantages over arrays
1) Dynamic size
2) Ease of insertion/deletionDrawback
1) Random access is not allowed
2) Need extra space for pointers
#include <iostream>
using namespace std;
/* Define our struct */
struct node
{
int data;
node *next;
};
/* Print a linked list */
void printList(node *h){
while (h != NULL){
cout << h->data << endl;
h = h->next;
}
}
/* Add a node at the front */
node* push(node *head, int new_data){
node *new_node = new node;
new_node->next = head;
new_node->data = new_data;
return new_node;
}
/* Add a node at the end */
void append(node *head, int new_data){
node *new_node = new node;
new_node->data = new_data;
new_node->next = NULL;
while (head->next != NULL){
head = head->next;
}
head->next = new_node;
}
/* Add a node after a given node */
void insertAfter(node *prev, int new_data){
if (prev == NULL){
cout << "The given previous node cannot be NULL";
return;
}
node *node_after = new node;
node_after->next = prev->next;
prev->next = node_after;
node_after->data = new_data;
}
int main(){
/* Creat three-member linked list */
node *head = new node;
node *second = new node;
node *third = new node;
head->next = second;
second->next = third;
third->next = NULL;
head->data = 0;
second->data = 1;
third->data = 2;
append(head, 5);
// node *node1 = push(head, 3);
printList(head);
return 0;
}
Binary Heap
Applications of Heaps:
1. Heap Sort: Heap Sort uses Binary Heap to sort an array in O(nLogn) time.
2. Priority Queue: Priority queues can be efficiently implemented using Binary Heap because it supports insert(), delete() and extractmax(), decreaseKey() operations in O(logn) time. Binomoial Heap and Fibonacci Heap are variations of Binary Heap. These variations perform union also efficiently.
3. Graph Algorithms: The priority queues are especially used in Graph Algorithms like Dijkstra’s Shortest Path and Prim’s Minimum Spanning Tree.
4. Many problems can be efficiently solved using Heaps. See following for example.
a) K’th Largest Element in an array.
b) Sort an almost sorted array/
c) Merge K Sorted Arrays.
Binary tree
Unlike linked list and array, binary tree is a hierarchical data structure. Its elements are root, child and leaves. Root is its topmost node, elements that connected to it higher level node is called its children, nodes that do not have any children is call leaves.
properity
- The maximum number of nodes at level
l
of a binary tree is
2l−1 - Maximum number of nodes in a binary tree of height
h
is
2h–1 . (prove: 1+2+4+...+2h−1=2h−1 ) - In a Binary Tree with
N
nodes, minimum possible height or minimum number of levels is
Log2(N+1) - A Binary Tree with
L
leaves has at least
Log2L+1 levels - In Binary tree, number of leaf nodes is always one more than nodes with two children.
- The maximum number of nodes at level
l
of a binary tree is
Types
Full Binary Tree, Complete Binary Tree, Perfect Binary Tree, Balanced Binary Tree, A degenerate (or pathological) tree.
See http://geeksquiz.com/binary-tree-set-3-types-of-binary-tree/Applications
- Manipulate hierarchical data.
- Make information easy to search (see tree traversal).
- Manipulate sorted lists of data.
- As a workflow for compositing digital images for visual effects.
- Router algorithms
Tree traversal
Below is an example of a binary tree and we are focusing on the problem to traverse a tree.
Depth First Traversals:
(1) Inorder
Algorithm Inorder(tree)
1. Traverse the left subtree, i.e., call Inorder(left-subtree)
2. Visit the root.
3. Traverse the right subtree, i.e., call Inorder(right-subtree)
result: 42513
(2) Preorder
Algorithm Preorder(tree)
1. Visit the root.
2. Traverse the left subtree, i.e., call Preorder(left-subtree)
3. Traverse the right subtree, i.e., call Preorder(right-subtree)
result: 12453
(3) Postorder
Algorithm Postorder(tree)
1. Traverse the left subtree, i.e., call Postorder(left-subtree)
2. Traverse the right subtree, i.e., call Postorder(right-subtree)
3. Visit the root.
result: 45231
Breadth first traversal:
METHOD 1 (Use function to print a given level)
/*Function to print level order traversal of tree*/
printLevelorder(tree)
for d = 1 to height(tree)
printGivenLevel(tree, d);
/*Function to print all nodes at a given level*/
printGivenLevel(tree, level)
if tree is NULL then return;
if level is 1, then
print(tree->data);
else if level greater than 1, then
printGivenLevel(tree->left, level-1);
printGivenLevel(tree->right, level-1);
METHOD 2 (Use Queue)
printLevelorder(tree)
1) Create an empty queue q
2) temp_node = root /*start from root*/
3) Loop while temp_node is not NULL
a) print temp_node->data.
b) Enqueue temp_node’s children (first left then right children) to q
c) Dequeue a node from q and assign it’s value to temp_node
How to Pick One?
- Extra Space can be one factor (Explained above)
- Depth First Traversals are typically recursive and recursive code requires function call overheads.
- The most important points is, BFS starts visiting nodes from root while DFS starts visiting nodes from leaves. So if our problem is to search something that is more likely to closer to root, we would prefer BFS. And if the target node is close to a leaf, we would prefer DFS.
Graph
Components
- Node: A finite set of vertices also called as nodes.
- Edge:A finite set of ordered pair of the form (u, v) called as edge.
Representations
- Adjacency Matrix
- Adjacency List
Traverse
- Breadth first traverse
- 2.