• A stack is a container of objects that are inserted and removed according to the last-in first-out (LIFO) principle. • In the pushdown stacks only two operations are allowed: • push the item into the stack, and pop the item out of the stack. • A stack is a limited access data structure - elements can be added and removed from the stack only at the top. • push adds an item to the top of the stack, pop removes the item from the top. • A helpful analogy is to think of a stack of books; you can remove only the top book, also you can add a new book on the top. • A stack may be implemented to have a bounded capacity. • If the stack is full and does not contain enough space to accept an entity to be pushed, the stack is then considered to be in an overflow state. • The pop operation removes an item from the top of the stack. • A pop either reveals previously concealed items or results in an empty stack, but, if the stack is empty, it goes into underflow state, which means no items are present in stack to be removed • Representation of a Stack using Arrays: • Let us consider a stack with 6 elements capacity. • This is called as the size of the stack. The number of elements to be added should not exceed the maximum size of the stack. • If we attempt to add new element beyond the maximum size, we will encounter a stack overflow condition. • Similarly, you cannot remove elements beyond the base of the stack. If such is the case, we will reach a stack underflow condition. • • Procedure: • STACK: Stack is a linear data structure which works under the principle of last in first out. • Basic operations: push, pop, display. • 1. PUSH: if (top==MAX), display Stack overflow else reading the data and making stack [top] =data and incrementing the top value by doing top++. • begin • if top = n then stack full • else • top = top + 1 • stack (top) : = item; • end • 2. Pop: if (top==-1), display Stack underflow else printing the element at the top of the stack and decrementing the top value by doing the top. • begin • if top = 0 then stack empty; • else • item := stack(top); • top = top - 1; • end; • 3. DISPLAY: IF (TOP==0), display Stack is empty else printing the elements in the stack from stack [0] to stack [top]. • Begin • if top = -1 then stack empty • item = stack[top] • return item • End • Linked List Implementation of Stack: • We can represent a stack as a linked list. In a stack push and pop operations are performed at one end called top. We can perform similar operations at one end of list using top pointer. • Queue • 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 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. • For implementing queue, we need to keep track of two indices, front and rear. We enqueue an item at the rear and dequeue an item from the front. • Front and rear variables point to the position from where insertions and deletions are performed in a queue. • Initially, the value of front and queue is -1 which represents an empty queue. • Array representation of a queue containing 5 elements along with the respective values of front and rear, is shown in the following figure. • The above figure shows the queue of characters forming the English word "HELLO". • Since, No deletion is performed in the queue till now, therefore the value of front remains -1 . • However, the value of rear increases by one every time an insertion is performed in the queue. • After inserting an element into the queue shown in the above figure, the queue will look something like following. • The value of rear will become 5 while the value of front remains same. • After deleting an element, the value of front will increase from -1 to 0. however, the queue will look something like following. Array Implementation of Queue • Algorithm to insert any element in a queue • Check if the queue is already full by comparing rear to max - 1. if so, then return an overflow error. • If the item is to be inserted as the first element in the list, in that case set the value of front and rear to 0 and insert the element at the rear end. • Otherwise keep increasing the value of rear and insert each element one by one having rear as the index. • Algorithm • Step 1: IF REAR = MAX - 1 Write OVERFLOW Go to step [END OF IF] • Step 2: IF FRONT = -1 and REAR = -1 SET FRONT = REAR = 0 ELSE SET REAR = REAR + 1 [END OF IF] • Step 3: Set QUEUE[REAR] = NUM • Step 4: EXIT •Algorithm to delete an element from the queue • If, the value of front is -1 or value of front is greater than rear , write an underflow message and exit. • Otherwise, keep increasing the value of front and return the item stored at the front end of the queue at each time. • Algorithm • Step 1: IF FRONT = -1 or FRONT > REAR Write UNDERFLOW ELSE SET VAL = QUEUE[FRONT] SET FRONT = FRONT + 1 [END OF IF] • Step 2: EXIT • Drawback of array implementation • Although, the technique of creating a queue is easy, but there are some drawbacks of using this technique to implement a queue. • Memory wastage : The space of the array, which is used to store queue elements, can never be reused to store the elements of that queue because the elements can only be inserted at front end and the value of front might be so high so that, all the space before that, can never be filled. Linked List implementation of Queue • In a linked queue, each node of the queue consists of two parts i.e. data part and the link part. Each element of the queue points to its immediate next element in the memory. • In the linked queue, there are two pointers maintained in the memory i.e. front pointer and rear pointer. • The front pointer contains the address of the starting element of the queue while the rear pointer contains the address of the last element of the queue. • The storage requirement of linked representation of a queue with n elements is o(n) while the time requirement for operations is o(1). • Insertion and deletions are performed at rear and front end respectively. If front and rear both are NULL, it indicates that the queue is empty. • Insert operation • The insert operation append the queue by adding an element to the end of the queue. The new element will be the last element of the queue. • In the first scenario, we insert element into an empty queue. In this case, the condition front = NULL becomes true. • The new element will be added as the only element of the queue and the next pointer of front and rear pointer both, will point to NULL. • Stack Applications: • 1. Stack is used by compilers to check for balancing of parentheses, brackets and braces. • 2. Stack is used to evaluate a postfix expression. • 3. Stack is used to convert an infix expression into postfix/prefix form. 4. In recursion, all intermediate arguments and return values are stored on the processor’s stack. • 5. During a function call the return address and arguments are pushed onto a stack and on return they are popped off. • 6. Depth first search uses a stack data structure to find an element from a graph • Applications of Queues: • 1. It is used to schedule the jobs to be processed by the CPU. • 2. When multiple users send print jobs to a printer, each printing job is kept in the printing queue. Then the printer prints those jobs according to first in first out (FIFO) basis. • 3. Breadth first search uses a queue data structure to find an element from a graph. • In-fix- to Postfix Transformation: • Procedure: Procedure to convert from infix expression to postfix expression is as follows: • 1. Scan the infix expression from left to right. • 2. • a) If the scanned symbol is left parenthesis, push it onto the stack. • b) If the scanned symbol is an operand, then place directly in the postfix expression (output). • c) If the symbol scanned is a right parenthesis, then go on popping all the items from the stack and place them in the postfix expression till we get the matching left parenthesis. • If the scanned symbol is an operator, then go on removing all the operators from the stack and place them in the postfix expression, if and only if the precedence of the operator which is on the top of the stack is greater than (or equal) to the precedence of the scanned operator and push the scanned operator onto the stack otherwise, push the scanned operator onto the stack. • Evaluating Arithmetic Expressions: • Procedure: • The postfix expression is evaluated easily by the use of a stack. • When a number is seen, it is pushed onto the stack; when an operator is seen, the operator is applied to the two numbers that are popped from the stack and the result is pushed onto the stack. Trees • Basic Tree Concepts: • A tree is non-linear and a hierarchical data structure consisting of a collection of nodes such that each node of the tree stores a value, a list of references to nodes (the “children”). • A tree is a non-empty set ,one element of which is designated the root of the tree while the remaining elements are partitioned into non-empty sets each of which is a sub-tree of the root. • A tree T is a set of nodes storing elements such that the nodes have a parent-child relationship that satisfies the following • • If T is not empty, T has a special tree called the root that has no parent. • • Each node v of T different than the root has a unique parent node w; each node with parent w is a child of w. Tree nodes have many useful properties. • The depth of a node is the length of the path (or the number of edges) from the root to that node. • The height of a node is the longest path from that node to its leaves. The height of a tree is the height of the root. • A leaf node has no children -- its only path is up to its parent. • 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 • Basic Terminology In Tree Data Structure: • Parent Node: The node which is a predecessor of a node is called the parent node of that node. {2} is the parent node of {6, 7}. • Child Node: The node which is the immediate successor of a node is called the child node of that node. Examples: {6, 7} are the child nodes of {2}. • Root Node: The topmost node of a tree or the node which does not have any parent node is called the root node. {1} is the root node of the tree. A non-empty tree must contain exactly one root node and exactly one path from the root to all other nodes of the tree. • Degree of a Node: The total count of subtrees attached to that node is called the degree of the node. The degree of a leaf node must be 0. The degree of a tree is the maximum degree of a node among all the nodes in the tree. The degree of the node {3} is 3. • Leaf Node or External Node: The nodes which do not have any child nodes are called leaf nodes. {6, 14, 8, 9, 15, 16, 4, 11, 12, 17, 18, 19} are the leaf nodes of the tree. • Ancestor of a Node: Any predecessor nodes on the path of the root to that node are called Ancestors of that node. {1, 2} are the parent nodes of the node {7} • Descendant: Any successor node on the path from the leaf node to that node. {7, 14} are the descendants of the node. {2}. • Sibling: Children of the same parent node are called siblings. {8, 9, 10} are called siblings. • Depth of a node: The count of edges from the root to the node. Depth of node {14} is 3. • Height of a node: The number of edges on the longest path from that node to a leaf. Height of node {3} is 2. • Height of a tree: The height of a tree is the height of the root node i.e the count of edges from the root to the deepest node. The height of the above tree is 3. • Level of a node: The count of edges on the path from the root node to that node. The root node has level 0. • Internal node: A node with at least one child is called Internal Node. • Neighbour of a Node: Parent or child nodes of that node are called neighbors of that node. • Subtree: Any node of the tree along with its descendant m-ary tree • m-ary tree (also known as k-ary or k-way tree) is a rooted tree in which each node has no more than m children. • A binary tree is the special case where m = 2, and a ternary tree is another case with m = 3 that limits its children to three. • Types of m-ary trees • A full m-ary tree is an m-ary tree where within each level every node has either 0 or m children. • A complete m-ary tree is an m-ary tree which is maximally space efficient. It must be completely filled on every level except for the last level. However, if the last level is not complete, then all nodes of the tree must be "as far left as possible". • A perfect m-ary tree is a full[1] m-ary tree in which all leaf nodes are at the same depth. An example of a m-ary tree with m=5 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. • A binary tree is either empty or consists of a node called the root together with two binary trees called the left subtree and the right subtree • Binary Tree Representation: 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 struct node { int data; struct node* left; struct node* right; }; • The height of the binary tree is the longest path from root node to any leaf node in the tree • In a binary tree, a node can have maximum two children. • Calculating minimum and maximum height from number of nodes – If there are n nodes in binary tree, maximum height of the binary tree is n-1 and minimum height is floor(log2n). • Strictly Binary tree: • If every non-leaf node in a binary tree has nonempty left and right subtrees, the tree is termed a strictly binary tree. • Thus the below tree of is strictly binary. A strictly binary tree with n leaves always contains 2n - 1 nodes. • Full Binary tree: • A full binary tree of height h has all its leaves at level h. • Alternatively; All non leaf nodes of a full binary tree have two children, and the leaf nodes have no children. For example, a full binary tree of height 3 contains = 15 nodes. • Complete Binary tree: • A binary tree with n nodes is said to be complete if it contains all the first n nodes of the above numbering scheme. Figure shows examples of complete binary trees. • A complete binary tree of height h looks like a full binary tree down to level h-1, and the level h is filled from left to right Tree Traversal • Traversal is a process to visit all the nodes of a tree and may print their values too. • Because, all nodes are connected via edges (links) we always start from the root (head) node. • That is, we cannot randomly access a node in a tree. There are three ways which we use to traverse a tree − • In-order Traversal • Pre-order Traversal • Post-order Traversal • we traverse a tree to search or locate a given item or key in the tree or to print all the values it contains. In-order Traversal • In this traversal method, the left subtree is visited first, then the root and later the right sub-tree. We should always remember that every node may represent a subtree itself. • If a binary tree is traversed in-order, the output will produce sorted key values in an ascending order. • We start from A, and following in-order traversal, we move to its left subtree B. B is also traversed in-order. • The process goes on until all the nodes are visited. The output of inorder traversal of this tree will be − •D → B → E → A → F → C → G • Pre-order Traversal • In this traversal method, the root node is visited first, then the left subtree and finally the right subtree • We start from A, and following pre-order traversal, we first visit A itself and then move to its left subtree B. B is also traversed pre-order. The process goes on until all the nodes are visited. The output of pre-order traversal of this tree will be − •A → B → D → E → C → F → G • Post-order Traversal • In this traversal method, the root node is visited last, hence the name. First we traverse the left subtree, then the right subtree and finally the root node. • We start from A, and following Post-order traversal, we first visit the left subtree B. B is also traversed post-order. The process goes on until all the nodes are visited. The output of post-order traversal of this tree will be − •D → E → B → F → G → C → A • Infix to postfix Conversion • Suppose Q is an arithmetic expression written in notation. • This algorithm finds the equivalence postfix expression P • 1. Scan Q from left to right and repeat step 2 to 5 for each element of Q until the STACK is empty • 2. If an operand is encountered, add it to P. • 3. If a left parenthesis is encountered, push it onto STACK. • 4. If an operator * is encountered, then: • a) Repeatedly pop from the STACK and add to P each operator (on the top of the STACK)which has the same precedence or higher precedence than * • b) Add * to STACK • 5. If a right parenthesis is encountered, then • a) Repeatedly pop from the STACK and add to P each operator until a left parenthesis is encountered • b) Remove the left parenthesis[Do not add left parenthesis to P] 6. Exit