Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 1

Similar documents
Lists, Stacks, and Queues. (Lists, Stacks, and Queues ) Data Structures and Programming Spring / 50

DATA STRUCUTRES. A data structure is a particular way of storing and organizing data in a computer so that it can be used efficiently.

DEEPIKA KAMBOJ UNIT 2. What is Stack?

EC8393FUNDAMENTALS OF DATA STRUCTURES IN C Unit 3

FORTH SEMESTER DIPLOMA EXAMINATION IN ENGINEERING/ TECHNOLIGY- OCTOBER, 2012 DATA STRUCTURE

Algorithms and Data Structures

The time and space are the two measure for efficiency of an algorithm.

Data Structure using C++ Lecture 04. Data Structures and algorithm analysis in C++ Chapter , 3.2, 3.2.1

MID TERM MEGA FILE SOLVED BY VU HELPER Which one of the following statement is NOT correct.

Solution: The examples of stack application are reverse a string, post fix evaluation, infix to postfix conversion.

DATA STRUCTURE UNIT I

Objective Questions for Online Practical Exams under CBCS Scheme Subject: Data Structure-I (CS-113)

FORTH SEMESTER DIPLOMA EXAMINATION IN ENGINEERING/ TECHNOLIGY- MARCH, 2012 DATA STRUCTURE (Common to CT and IF) [Time: 3 hours

DATA STRUCTURES AND ALGORITHMS UNIT I LINEAR STRUCTURES

Linked List. April 2, 2007 Programming and Data Structure 1

Postfix (and prefix) notation

CSE 230 Intermediate Programming in C and C++

CS301 - Data Structures Glossary By

Introduction. Problem Solving on Computer. Data Structures (collection of data and relationships) Algorithms

An Introduction to Trees

MIDTERM EXAMINATION Spring 2010 CS301- Data Structures

VTU NOTES QUESTION PAPERS NEWS RESULTS FORUMS THE STACK

DATA STRUCTURE : A MCQ QUESTION SET Code : RBMCQ0305

MULTIMEDIA COLLEGE JALAN GURNEY KIRI KUALA LUMPUR

12 Abstract Data Types

Outline. Introduction Stack Operations Stack Implementation Implementation of Push and Pop operations Applications. ADT for stacks

Fundamentals of Data Structure

Stacks, Queues and Hierarchical Collections. 2501ICT Logan

STACKS. A stack is defined in terms of its behavior. The common operations associated with a stack are as follows:

Data Structure. IBPS SO (IT- Officer) Exam 2017

Content: Learning Objectives

FINALTERM EXAMINATION Fall 2009 CS301- Data Structures Question No: 1 ( Marks: 1 ) - Please choose one The data of the problem is of 2GB and the hard

Stack. 4. In Stack all Operations such as Insertion and Deletion are permitted at only one end. Size of the Stack 6. Maximum Value of Stack Top 5

Stacks, Queues (cont d)

STACKS AND QUEUES. Problem Solving with Computers-II

A. Year / Module Semester Subject Topic 2016 / V 2 PCD Pointers, Preprocessors, DS

Data Structures Week #3. Stacks

DATA STRUCTURES AND ALGORITHMS

DOWNLOAD PDF LINKED LIST PROGRAMS IN DATA STRUCTURE

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING B.E SECOND SEMESTER CS 6202 PROGRAMMING AND DATA STRUCTURES I TWO MARKS UNIT I- 2 MARKS

Some Applications of Stack. Spring Semester 2007 Programming and Data Structure 1

Stacks, Queues and Hierarchical Collections

3. Fundamental Data Structures

Lecture Data Structure Stack

Types of Data Structures

List, Stack, and Queues

MAHARASHTRA STATE BOARD OF TECHNICAL EDUCATION

1 P age DS & OOPS / UNIT II

Data Structure using C++ Lecture 04. Data Structures and algorithm analysis in C++ Chapter , 3.2, 3.2.1

// The next 4 functions return true on success, false on failure

Data Structure with C. List

CP2 Revision. theme: dynamic datatypes & data structures

Cpt S 122 Data Structures. Course Review Midterm Exam # 1

Answers. 1. (A) Attempt any five : 20 Marks

DHANALAKSHMI COLLEGE OF ENGINEERING DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING EC6301 OBJECT ORIENTED PROGRAMMING AND DATA STRUCTURES

Linked Lists. Linked list: a collection of items (nodes) containing two components: Data Address (link) of the next node in the list

Linked Lists. Linked list: a collection of items (nodes) containing two components: Data Address (link) of the next node in the list

CS DATA STRUCTURES AND ALGORITHMS

LIFO : Last In First Out

Stack ADT. ! push(x) puts the element x on top of the stack! pop removes the topmost element from the stack.

Data Structures & Algorithm Analysis. Lecturer: Souad Alonazi

MAHARASHTRA STATE BOARD OF TECHNICAL EDUCATION (Autonomous) (ISO/IEC Certified)

Data Structures. Chapter 06. 3/10/2016 Md. Golam Moazzam, Dept. of CSE, JU

infix expressions (review)

Dynamic Data Structures. John Ross Wallrabenstein

Formal Languages and Automata Theory, SS Project (due Week 14)

CSE 214 Computer Science II Stack

DATA STRUCTURE. Exclusive for IACE Students iacehyd.blogspot.in Ph: /422 Page 1

1. Two main measures for the efficiency of an algorithm are a. Processor and memory b. Complexity and capacity c. Time and space d.

IV. Stacks. A. Introduction 1. Consider the 4 problems on pp (1) Model the discard pile in a card game. (2) Model a railroad switching yard

CS8391-DATA STRUCTURES QUESTION BANK UNIT I

STACKS 3.1 INTRODUCTION 3.2 DEFINITION

Lecture No.04. Data Structures

Data Structures and Algorithms for Engineers

Stacks and Queues. CSE Data Structures April 12, 2002

Stacks. stacks of dishes or trays in a cafeteria. Last In First Out discipline (LIFO)

Revision Statement while return growth rate asymptotic notation complexity Compare algorithms Linear search Binary search Preconditions: sorted,

CHARUTAR VIDYA MANDAL S SEMCOM Vallabh Vidyanagar

Data Structure - Stack and Queue-

INSTITUTE OF AERONAUTICAL ENGINEERING

MAHARASHTRA STATE BOARD OF TECHNICAL EDUCATION (Autonomous) (ISO/IEC Certified)

Arrays and Linked Lists

UNIT - I LISTS, STACKS AND QUEUES

DDS Dynamic Search Trees

Basic Data Structures (Version 7) Name:

Introduction to Data Structure

CS 8391 DATA STRUCTURES

Operations on Heap Tree The major operations required to be performed on a heap tree are Insertion, Deletion, and Merging.

March 13/2003 Jayakanth Srinivasan,

Problem with Scanning an Infix Expression

CS 270 Algorithms. Oliver Kullmann. Binary search. Lists. Background: Pointers. Trees. Implementing rooted trees. Tutorial

R10 SET - 1. Code No: R II B. Tech I Semester, Supplementary Examinations, May

CS8391-DATA STRUCTURES

First Semester - Question Bank Department of Computer Science Advanced Data Structures and Algorithms...

4.1 COMPUTATIONAL THINKING AND PROBLEM-SOLVING

DATA STRUCTURES AND ALGORITHMS

17CS33:Data Structures Using C QUESTION BANK

ADVANCED DATA STRUCTURES USING C++ ( MT-CSE-110 )

Heap Management. Heap Allocation

Dynamic Data Structures

Transcription:

Basics : Abstract Data Type(ADT) introduction to data structures representation - implementation Stack and list: representing stack implementation application balancing symbols conversion of infix to postfix expression evaluating a postfix expression recursive function call Linked list ADT implementation using arrays limitations - linked list using dynamic variables- linked implementation of stacks circular list doubly linked lists Abstract Data Types (ADTs) An Abstract Data Type (ADT) is a set of operations. Abstract data types are mathematical abstractions; nowhere in an ADT's definition is there any mention of how the set of operations is implemented. This can be viewed as an extension of modular design. Objects such as lists, sets, and graphs, along with their operations, can be viewed as abstract data types, just as integers, reals, and booleans are data types. Integers, reals, and booleans have operations associated with them, and so do abstract data types. For the set ADT, there are various operations as union, intersection, size, and complement. Alternately, the two operations union and find, which would define a different ADT on the set. The basic idea is that the implementation of these operations is written once in the program, and any other part of the program that needs to perform an operation on the ADT can do so by calling the appropriate function. If for some reason implementation details need to change, it should be easy to do so by merely changing the routines that perform the ADT operations. This change, in a perfect world, would be completely transparent to the rest of the program. Data structures Data Structures is a means of storing a collection of data. It is the specification of the elements of the structure, the relationship between them and the operations that may be performed upon them. Classification of data structures it. Data structures can be classified based on the organization and the operations defined on Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 1

Linear and non-linear structure: Simple data structures can be combined in various ways to form more complex structure. There are two kinds of complex data structure. They are linear & non-linear, depending on the complexity of the logical relationship they represent Linear data structure : Stacks, queues, linear linked list, arrays Non- linear data structure: Tree and graph tables, sets Data is a set of elementary items. The possible ways in which the data items are logically related is defined by data structure. That is, organized collection of data is called a data structure. The programs have to follow a certain rules to access and process the structure data. And so, Data structure = Organised data + Allowed Operation. These are standard data structures which are often used to form the basis for computer data structures. Arrays are the basic building blocks for more complex data structures. Classifications: Data structures Linear Non Linear Linear Data Structures: Items are arranged in Linear sequence like an array. Eg. Arrays,Linked list,stacks,queues. Non Linear data Structures: Data Items are not in sequence. Eg. Tree, Graph Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 2

Data structures are classified depending on the area of applications. Of them few data structures are there which are frequently used almost in all applications areas. Fundamental Data Structures Linear Data Structures Non Linear Data Structures ARRAYS LINKED LISTS STACKS QUEUES TREES GRAPHS TABLES SETS STACK A stack is an ordered collection of data items. New data items may be inserted or deleted in a stack. But these insertion (PUSH) and deletion (POP) operation can be done only at one end called the top of the stack. Top is a pointer which always point to the top of the stack. QUEUES: A queue is an ordered collection of items from which items may be deleted at one end called the front, and into which items may be inserted at the other end called rear of the queue. Example: Front A B C Rear In this example, A is at the front of the queue and C is at the rear. An element has been deleted from the front of the queue. i.e., Front Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 3

B C Rear and items can be inserted at the rear of the queue. i.e., Front B C D The first element inserted into a queue is the first element to be removed. For this reason, a Rear queue is sometimes called a FIFO list. (First In First Out) Operations involved in a queue: 1. Create a queue. 2. Check whether a queue is empty. 3. Check whether the queue is full. 4. Add item at the rear queue. 5. Remove item from front of queue. 6. Read the front of queue. 7. Print the entire queue. In the single linked list each link has single link to the next node. It is otherwise called as linear linked list. It contains the head pointer which holds the address of the first node. Using head pointer only we can access entire linked list. The below diagram shows the single linked In single linked list we can traverse in one direction from head to null. We cant move in reverse direction i.e. from null to head. Link field of last node have the null pointer indicates the end of the list. Operations In Single Linked List: We can insert and delete the node in a single linked list. Inserting The Node Into A Single Linked List: Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 4

Consider the linked list: TREE: is defined as a finite set of one or more nodes such that there is one specially designated node called ROOT and the remaining nodes are partitioned into a collection of sub-trees of the root each of which is also a tree. Example A LEVEL 0 B C 1 D E F G 2 H I J 3 NODE: stands for item of information. The nodes of a tree have a parent-child relationship. The root does not have a parent ; but each one of the other nodes has a parent node associated to it. A node may or may not have children is called a leaf node or terminal nodes. GRAPH DEFINING GRAPH: A graphs g consists of a set V of vertices (nodes) and a set E of edges (arcs). We write G=(V,E). V is a finite and non-empty set of vertices. E is a set of pair of vertices; these pairs are called as edges. Therefore, V(G).read as V of G, is a set of vertices and E(G),read as E of G is a set of edges. An edge e=(v, w) is a pair of vertices v and w, and to be incident with v and w. A graph can be pictorially represented as follows, 1 2 3 4 Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 5

FIG: Graph G We have numbered the graph as 1,2,3,4. Therefore, V(G)=(1,2,3,4) and E(G) = (1,2),(1,3),(1,4),(2,3),(2,4). TABLE A symbol table is a set of locations containing a record for each identifier with fields for the attribute of the identifier. A symbol table allows us to find the record fro each identifier (variable) and to store or retrieve data from that record quickly. STACKS A stack is an ordered collection of data items into which new items may be inserted or from which items may be deleted at one end, called the top of the stack. Stack can be represented formally as Top to C B A The restriction on a stack implies that the last element to be inserted into the stack will be the first to be removed. For this reason, stack is also referred to as Last In First Out (LIFO) lists. Basic Operation On A Stack: - The basic operations on a stack are as follows: 1.Create a stack 2.Push an element onto a stack (if not full) 3.Pop an element from a stack (if not empty) 4.initialize a stack 5.Print the entire stack 6.read a stack top (without removing it and if not empty) Implementation: Stack can be implemented as one of the following data structures: Array Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 6

Linked list Now let us see about array implementation, linked list implementation may be explained later. Array Implementation: - The simplest way to represent a stack is by using one dimensional array. One end of the array is the fixed bottom of the stack while the top of the stack constantly shifts as items are popped and pushed. Thus another field is needed to keep track of the current position of the top of the stack. A stack in C may therefore of the stack as a structure containing two objects: * An array to hold the elements of the stack and * an integer to indicate the position of the current stack top within the array. Example: # define STACKSIZE 100 struct stack int top; int items [STACKSIZE]; ; Once this has been done, an actual stack s may be declared as struct stack s; In this example, STACKSIZE is set to 100 to indicate that the stack can contain 100 elements from 0... 99 and also that data type of the elements need not be an integer. It may be of float or any other data type. The identifier top must always be declared as an integer. If its value of s.top is 4, then we have five elements on the stack s.item [0], s.item [1], s.item [2], s.item [3], s.item [4]. When the stack is popped, the value of s.top is changed to 3 to indicate that there are only 4 elements on the stack and s.item [3] is the top element. On the other hand, if a new object is pushed onto the stack, the value of s.top must be increased by 1 i.e., from 4 to 5 and the new object is inserted into the position s.item [5]. OPERATIONS: Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 7

Empty Operation: Empty stack contains no elements can be initialized by -1 i.e., s.top = -1. Implementation: int empty (struct stack *ps) if (ps -> top == -1) return (TRUE); else return (FALSE); Once this function exists, the statement implements a test for the empty stack if (empty (&s)) /* Stack is empty */ else /* Stack is not empty */ Here, we are passing the address of the structure to the function. So the condition empty (&s) implies that we are checking the condition s.top == -1. POP OPERATION:- POP operation removes an element from the stack. An attempt to pop an element from the stack, when the array is empty, causes an underflow. Pop operation involves: 1. Check whether the array is empty before attempting to pop another element. If so halt execution. 2. Decrement the top pointer. 3. Pop the element from the top of the stack. ALGORITHM: Variables used: S Array to hold elements TOP Denotes the top element in the stack Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 8

Function POP(S,TOP) 1. [Check for underflow on stack] If TOP = 0 Then Write( STACK UNDERFLOW ON POP ) Take action in response to underflow Exit 2. [Decrement pointer] TOP TOP 1 3. [Return former top element of stack] Implementation Return(S[TOP + 1]) int pop (struct stack *ps) if (empty (ps)) cout << "Stack underflow"; exit (1); return ps -> items [ps -> top - -]); Here, if the stack is not empty, the top element of the stack is retained as the returned value. This element is then removed from the stack by the expression ps-> top - -. For example, consider there are 88 items on the stack. When the pop is called, ps -> top equals 87 i.e., items are numbers from 0... 87. The value of ps -> items [87] is returned and the value of ps -> top is changed to 86. Here, ps -> items [87] still retains its old value i.e., the array ps -> items remains unchanged by the call to pop. However, the stack is modified, since it now contains only 87 elements rather than 88. If the pop function is called with an empty stack, the function prints the error message stack underflow and execution halts. PUSH OPERATION: Push operation inserts an element onto the stack. Stack is a dynamic structure that is Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 9

constantly allowed to grow and shrink and thus changes its size. But now we represented the stack by means of array. An attempt to push an element onto the stack, when the array is full, causes an overflow. Push operation involves: 1.Check whether the array is full before attempting to push another element. If so halt execution. ALGORITHM: Variables used: 2. Increment the top pointer. 3. Push the element onto the top of the stack S Array to hold elements N Total no of elements TOP Denotes the top element in the stack X The element to be inserted at the top of a stack Procedure PUSH(S,TOP,X) 1. [Check for stack overflow] If TOP>N then Write('STACK OVERFLOW') Return 2. [Increment TOP] TOP TOP+1 3. [Insert element] S[TOP] X 4. [Finished] Return Implementation: void push (struct stack *ps, int x) if (ps -> top == STACKSIZE-1) cout <<"Stack overflow"); exit (1); Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 10

else ps -> item [++ (ps -> top)] = x; return; Here, ps -> top always points to the top element of the stack. So, if to push operation is called, the top element position will be incremented, and there value of x will be stored using ps ->item [++ (ps -> top). For example, if ps -> top = 87 and push is called, ps -> top will be changed to 88 and the new element will be stored in ps -> item [88] i.e., as 89 the element in an array. If maximum size of an array is 88, and when push is called, first ps -> top value will be tested whether it is equivalent to 87. If it is so, further we cannot push an element into the stack and therefore, error message will be displayed. READ STACK TOP This operation returns the top element of the stack without removing it from the stack. Implementation int stacktop (struct stack *ps) if (empty (ps)) cout <<"Stack underflow"); exit (1); else return (ps -> items [ps -> top]); This operation involves: 1. If the stack is empty, print a warning message and halt execution. 2. Read the top element from the stack and return to the calling program. Difference between pop operation and stack top operation is, here we didn't decrement Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 11

ps-> top to point to the next element as the top element. Top element remains the same. APPLICATIONS OF STACKS: Two applications of stacks are : (i) RECURSION (ii) COMPILATION OF INFIX EXPRESSIONS (i) RECURSION:- Recursion is the name given to the technique of defining a set or a process in terms of itself. The factorial function, whose domain is the natural numbers, can be recursively defined as FACTORIAL(N) = 1, if N = 0 N * FACTORIAL(N-1), otherwise Here FACTORIAL(N) is defined in terms of FACTORIAL(N-1), which in turn is defined in terms of FACTORIAL(N-2), etc., until finally FACTORIAL(0) is reached, whose value is given as one. A procedure that contains a procedure call to itself, or a procedure call to a second procedure which eventually causes the first procedure to be called, is known as a recursive procedure. Conditions to be satisfied by recursive procedure First, each time a procedure calls itself (either directly or indirectly), it must be nearer, in some sense, to a solution. In the case of the factorial function, each time that the function calls itself, its argument is decremented by one, so the argument of the function is getting smaller. Second, there must be a decision criterion for stopping the process or computation. In the case of the factorial function, the value of n must be zero. The general algorithm model for any recursive procedure contains the following steps: 1. [Prologue] Save the parameter, local variables, and return address. 2. [Body] If the base criterion has been reached, then perform the final computation and go to step 3; otherwise the partial computation and go to step 1 3. [Epilogue] Restore the most recently saved parameters, local variables, and return address. Go to this return address. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 12

(ii)expressions: - Usual algebraic notation is often termed infix notation. Here, the arithmetic operator appears between the two operands to which it is being applied. There are two alternate notations for expressing the expression. These are prefix and postfix expressions. Example: A + B INFIX + A B PREFIX A B + POSTFIX The prefixes "pre -", "post -" and "in -" refer to the relative position of the operator with respect to the two operands. In prefix notation, the operator precedes the two operands, in postfix notation, the operator follows the two operands and in infix notation, the operator is between the operands. To understand the expression, we must first decide the order of evaluation of an expression. In C language, the operator with highest priority is evaluated first. Each operator is given certain priority. Priority of arithmetic operators in C: * / High + - Low If the expression consists of more than one operator at the same level, then it follows left associativity rule. I.e., operator at left most will be done first and so evaluated from left to right. Example: A + B * C Here, first B * C will be evaluated and then added with the value of A. In case, if we want to evaluate A + B first i.e., if we want to override the rules, the expression should be parenthesized. Such expressions are always evaluated with the innermost parenthesized expression first. i.e., (A + B) * C Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 13

CONVERSION OF INFIX TO POSTFIX / PREFIX EXPRESSION: - The following three steps are to be carried out to convert the infix expression to postfix expression. 1. Completely parenthesize the infix expression to specify the order of all the operations. 2. Move each operator to the space held by its corresponding right parenthesis. 3. Remove all parentheses. Example: Consider the following expression. A / B * C + D * E - A * C 1. Completely parenthesizing this expression yields ((((A / B) * C) + (D * E)) - (A * C)) 2. Moving each operator to its corresponding right parenthesis, we obtain ((((A / B) * C) + (D * E)) (A* C)) 3. Removing all parentheses, we are left with postfix form A B / C * D E * + A C * - In a similar way, the conversion algorithm for infix to prefix specifies that, after completely parenthesizing the infix expression with order of priority in mind, we move each operator to its corresponding left parenthesis. Applying the method to A / B * C + D * E - A * C gives us ((((A / B) * C) + (D * E)) (A* C)) and finally the prefix form: - + * / A B C * D E * A C The importance of postfix and prefix notations in arithmetic expressions is that these notations are completely free of parenthesis. Consequently an expression in postfix / prefix is in unique form. Consider an example in infix expression: Z = A * B / C + D Z = (A * B) / C + D Z = ((A * B) / C) + D Even though expressions are written in different forms, the result will be the same. The process of collapsing such different expressions into one unique form is called parsing the expression, and frequently used method of parsing relies heavily upon stacks. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 14

In the design of compliers, this passing of an expression into postfix form is crucial because having a unique form for an expression greatly simplifies its evaluation. Thus, in handling an argument statement, a complier must: 1. Parse it into postfix form. 2. Apply an evaluation algorithm to the postfix form. Implementation: To implement the conversion of infix expression to postfix form, the three step procedure is not enough. Instead we'll use an algorithm that has its essential data structures: 1.A string INFIX containing the infix expression 2.A stack opstk, which may contain: - All arithmetic operators - Parenthesis " ( and ) " - Null character " \0 " 3.A string POSTFIX containing the final postfix expression. The description of the algorithm is as follows: 1.Define a function PRIORITY, which takes an operator, parentheses, or ' \o ' as its argument and returns an integer as described in the table below. Character * / + - ( ) \0 Returned value 2 2 1 1 0 0 0 3.Push ' \o ' out OPSTACK as its first entry 4.Read the next character CH from the INFIX string 5.Test CH and: - If CH is an operand, append it to the POSTFIX string - If CH is a left parenthesis, then push CH onto the stack - If CH is a right parenthesis. then pop entries from stack and append them to POSTFIX until a left parenthesis is popped. Discard both left and right parentheses. - If CH is ' \o ', pop all entries that remain on the stack and append them to the POSTFIX string Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 15

- Otherwise, pop from the stack and append to the POSTFIX string, whose STACK - PRIORITY is greater than or equal to the INFIX - PRIORITY of CH. Then stack CH. 6. Repeat step (4) and (5) until CH becomes ' \o. CH OPSTACK POSTFIX COMMENT 1 Push ' \o ' 2 A Reach ch 3 A Append CH to Postfix 4 * Read CH 5 * \0 STACK Ch 6 B Read CH 7 AB Append CH to Postfix 8 + Read CH Pop *, Append * to postfix, 9 AB* Push CH 10 ( Read ch 11 (+ \0 Push ch 12 C Read CH 13 AB * C Append CH to Postfix 14 0 Read CH 15 - (+ \0 push ch 16 D Read CH 17 AB * CD Append CH to Postfix 18 / read CH 19 / - (+ \0 push ch 20 E Read CH 21 AB * CDE Append CH to Postfix 22 ) Read CH Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 16

23 + \0 AB * CDE /- Pop & Append to postfix until (reached 24 \0 Read CH 25 AB * CDE / - + \0 Pop & Append to rest of stack to ch FIG: Translation of the infix expression A * B + (C-D/E) using the algorithm in the text. EVALUATING POSTFIX EXPRESSION: Once the expression has been parsed into postfix form, another stack can be used to evaluate postfix expression. As an example, consider the postfix expression, AB*CDE/-+ \0 Let us suppose that A,B,C,D and E are the symbols used associated with values Symbol value A 5 B 3 C 6 D 8 E 2 To evaluate such an expression, we repeatedly read characters from the postfix expression. If the character read is an operand, push the value associated with it onto the stack. If it is an operator, pop two values from the stack, apply the operator to them and push the result back on the stack. The process is illustrated in the following figure. Read A Read B Read * Read C 5 3 5 15 6 15 Read D Read E Read / Read- Read+ Read \0 2 8 8 4 Prepared by 6 Mrs.D.Maladhy 6 6 (AP/IT/RGCET) 2 17 Page 17 15 15 15 15

Implementation: Data Structures Used: Description: End of postfix expression. Answer is on top of stack. FIG: Evaluation of AB*CDE/-+\0. 1. A stack opndstk is used to hold the operands. 2. A string containing the postfix expression. 1.Make OPNDSTK sd empty 2.Read c 3.Test c and - if it is an operand,push the value on stack. - Otherwise,pop top two entries/operands from the stack and apply the operator just read. Then stack the value. 1. Repeat steps 2 and 3 until \0 reaches and pop the final value from the stack. C Opnd1 Opnd2 Value Opndstk 6 6 2 6,2 3 6,2,3 + 2 3 5 6,5-6 5 1 1 3 6 5 1 1,3 8 6 5 1 1,3,8 2 6 5 1 1,3,8,2 / 8 2 4 1,3,4 + 3 4 7 1,7 Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 18

* 1 7 7 7 \0 pop_stack and return the value FIG: Evaluating the POSTFIX expression: 623+-382/+* Since input values are read as characters, we have to convert the operand characters to numbers and the operator characters to operation. For example, we have to find a method for converting the character 5 to the number 5 and the character + to the addition operation. To convert a single digit character x in c,the expression x- 0 yields the numerical value of that digit. And then we have to write the function that accepts the character representation of an operator and two operands as input parameters and returns the value of the expression obtained by applying the operator to the operands. LINKED LISTS: DRAWBACKS OF ARRAY IMPLEMENTATIONS OF A LIST: 1. Memory storage space is wasted; very often the list is much shorter than the array size declared. 2. List cannot grow in its size beyond the size of the declared array if required during program execution. 3. Operations like insertion and deletion at a specified location in a list requires a lot of movement of data, therefore, leading to inefficient and line consuming algorithms. LIST LIST LIST (0) BLUE LIST (0) BLUE (1) RED (1) RED (2) YELLOW (2) YELLOW GREEN (3) (3) ORANGE ORANGE WHITE (4) (4) PINK (5) (5) (6) (6) FIG(1) FIG(2) Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 19

If we want to insert data between GREEN and ORANGE, the data ORANGE is to be moved down. if the data GREEN is to be WHITE declared,other data items ORANGE,WHITE AND PINK are to be moved up one position. ADVANTAGES: 1.The primary advantage of linked lists over arrays is that linked lists can grow and shrink during their lifetime (ie) maximum size ned not be known in advance. 2.They provide quick access to any item in the list which increases the efficiency of rearranging data items. Pointers are capable of representing a much more complex relationship between elements of a structure than a linear order. The use of pointers or links to refer to elements of a data structure implies that elements which are logically adjacent need not be physically adjacent in memory. This type of allocation is called linked allocation. Now, let us see how to represent data structures by linked allocation. Under this, a list has been defined to consist of an ordered set of elements which may vary in number. SINGLY / LINEAR LINKED LIST: In a sequential representation, suppose that the items were implicitly ordered, that is, each item contained within itself the address of the next item, such an implicit ordering gives rise to a data structure known as a Linear linked list or Singly linked list which is shown in figure: INFO NEXT INFO NEXT INFO NEXT HEAD NULL node node TAIL node FIG:linear linked list. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 20

Each node consists of two fieds, - information field called INFO that holds the actual element on the list and - a pointer pointing to next element of the list called LINK,ie. It holds the address of the next element. The name of a typical element is denoted by NODE. Pictorially, the node structure is given as follows: NODE INFO LINK It is assumed that an available area of storage for this node structure consists of a stack of available nodes,as shown below: AVAIL... Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 21

Here, the pointer variable AVAIL contains the address of the top node in the stack. The head and tail are pointers pointing to first and last element of the list repectively. For an empty list the head and tail have the value NIL. When the list has one element, the head and tail point to the same. OPERATIONS: INSERTION IN A LIST: Inserting a new item,say x,into the list has three situations: 1. Insertion at the front of the list 2. Insertion in the middle of the list or in the order 3. Insertion at the end of the list INSERTION AT FRONT: Algorithms for placing the new item at the beginning of a linked list: 1. Obtain space for new node 2. Assign data to the item field of new node 3. Set the next field of the new node to point to the start of the list 4. Change the head pointer to point to the new node. Step 1: NEW Return(NEW) FIRST 20 30 40 NULL Step 2: NEW 10 FIRST 20 30 40 NULL Step 3: FIRST 10 20 30 40 NULL Algorithm for inserting the new node x between the two existing nodes, say N1 and N2( or Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 22

in order): 1. Set space for new node x 2. Assign value to the item field of x 3. Search for predecessor node n1 of x 4.Set the next field of x to point to link of node n1(node N2) 5.Set the next field of N1 to point to x. Function INSORD(X, FIRST) Step 1: NEW FIRST 20 30 40 NULL Step 2: NEW 25 FIRST 20 30 40 NULL SAVE Step 3: 25 FIRST 20 30 40 NULL SAVE Step 4: FIRST 20 25 30 40 NULL Algorithms for inserting an item at the end of the list: 1.Set space for new node x 2.Assign value to the item field of x 3.Set the next field of x to NULL Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 23

4.Set the next field of N2 to point to x Step 1: FIRST NEW 20 30 40 NULL Step 2: FIRST NEW 50 NULL 20 30 40 NULL SAVE Step 3: NEW 50 NULL Step 4: FIRST 20 30 40 SAVE FIRST 20 30 40 50 NULL Note that no data is physically moved, as we had seen in array implementation. Only the pointers are readjusted. DELETING AN ITEM FROM A LIST: Deleting a node from the list requires only one pointer value to be changed, there we have situations: 1.Deleting the first item 2.Deleting the last item 3.Deleting between two nodes in the middle of the list. Algorithms for deleting the first item: 1.If the element x to be deleted is at first store next field of x in some other variable y. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 24

2.Free the space occupied by x 3.Change the head pointer to point to the address in y. Algorithm for deleting the last item: 1.Set the next field of the node previous to the node x which is to be deleted as NULL 2.Free the space occupied by x Algorithm for deleting x between two nodes N1 and N2 in the middle of the list: 1.Set the next field of the node N1 previous to x to point to the successor field N2 of the node x. 2.Free the space occupied by x. LIST The general list is of the form a1, a2, a3,..., an. The size of this list is n. For any list except the null list, ai+l follows (or succeeds) ai (i < n) and that ai-1 precedes ai (i > 1). The first element of the list is a1, and the last element is an. The position of element ai in a list is i. Some popular operations are print_list and make_null, which do the obvious things; find, which returns the position of the first occurrence of a key; insert and delete, which generally insert and delete some key from some position in the list; and find_kth, which returns the element in some position (specified as an argument). If the list is 34, 12, 52, 16, 12, then find(52) might return 3; insert(x,3) might makes the list into 34, 12, 52, x, 16, 12 (if we insert after the position given); and delete(3) might turn that list into 34, 12, x, 16, 12. Simple Array Implementation of Lists Obviously all of these instructions can be implemented just by using an array. Even if the array is dynamically allocated, an estimate of the maximum size of the list is required. Usually this requires a high over-estimate, which wastes considerable space. This could be a serious limitation, especially if there are many lists of unknown size. An array implementation allows print_list and find to be carried out in linear time, which is as good as can be expected, and the find_kth operation takes constant time. However, Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 25

insertion and deletion are expensive. For example, inserting at position 0 (which amounts to making a new first element) requires first pushing the entire array down one spot to make room, whereas deleting the first element requires shifting all the elements in the list up one, so the worst case of these operations is O(n). On average, half the list needs to be moved for either operation, so linear time is still required. Merely building a list by n successive inserts would require quadratic time. Because the running time for insertions and deletions is so slow and the list size must be known in advance, simple arrays are generally not used to implement lists. Comparison of Methods Which is the best? A pointer-based or array-based implementation of lists. Often the answer depends on which operations intended to perform, or on which are performed most frequently. Other times, the decision rests on how long the list is likely to get. The principal issues to consider are the following. 1. The array implementation requires us to specify the maximum size of a list at compile time. If a bound cannot be put on the length to which the list will grow, probably choose a pointer-based implementation. 2. Certain operations take longer in one implementation than the other. For example, INSERT and DELETE take a constant number of steps for a linked list, but require time proportional to the number of following elements when the array implementation is used. Conversely, executing PREVIOUS and END require constant time with the array implementation, but time proportional to the length of the list if pointers are used. 3. If a program calls for insertions or deletions that affect the element at the position denoted by some position variable, and the value of that variable will be used later on, then the pointer representation cannot be used. As a general principle, pointers should be used with great care and restraint. 4. The array implementation may waste space, since it uses the maximum, amount of space independent of the number of elements actually on the list at any time. The pointer implementation uses only as much space as is needed for the elements currently on the Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 26

list, but requires space for the pointer in each cell. Thus, either method could wind up using more space than the other in differing circumstances. LINKED LISTS In order to avoid the linear cost of insertion and deletion, ensure that the list is not stored contiguously, since otherwise entire parts of the list will need to be moved. Figure shows the general idea of a linked list. A linked list Linked list with actual pointer values The linked list consists of a series of structures, which are not necessarily adjacent in memory. Each structure contains the element and a pointer to a structure containing its successor. We call this the next pointer. The last cell's next pointer points to NULL - this value is defined by C and cannot be confused with another pointer. ANSI C specifies that as zero. A pointer variable is just a variable that contains the address where some other data is stored. Thus, if p is declared to be a pointer to a structure, then the value stored in p is interpreted as the location, in main memory, where a structure can be found. A field of that structure can be accessed by pfield_name, where field_name is the name of the field. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 27

Figure 2 shows the actual representation of the list in the Figure 1. The list contains five structures, which happen to reside in memory locations 1000, 800, 712, 992, and 692 respectively. The next pointer in the first structure has the value 800, which provides the indication of where the second structure is. The other structures each have a pointer that serves a similar purpose. Of course, in order to access this list, it is necessary to know where the first cell can be found. A pointer variable can be used for this purpose. It is important to remember that a pointer is just a number. Deletion from a linked list Insertion into a linked list To execute print_list(l) or find(l,key), pass a pointer to the first element in the list and then traverse the list by following the next pointers. This operation is clearly linear-time, although the constant is likely to be larger than if an array implementation were used. The find_kth operation is no longer quite as efficient as an array implementation; find_kth(l,i) takes O(i) time and works by traversing down the list in the obvious manner. The delete command can be executed in one pointer change. Once an element is deleted, the pointer of its previous element should be made to point to the next element. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 28

The insert command requires obtaining a new cell from the system by using an malloc call (more on this later) and then executing two pointer maneuvers. The dashed line represents the old pointer. Problems encountered First of all, there is no really obvious way to insert at the front of the list from the definitions given. Second, deleting from the front of the list is a special case, because it changes the start of the list; careless coding will lose the list. A third problem concerns deletion in general. Although the pointer moves above are simple, the deletion algorithm requires us to keep track of the cell before the one that we want to delete. Linked list with a header It turns out that one simple change solves all three problems. Keep a sentinel node, which is sometimes referred to as a header or dummy node. To avoid the problems associated with deletions, write a routine find_previous, which will return the position of the predecessor of the cell that is to be deleted. If a header is used, then if the first element in the list is to be deleted, find_previous will return the position of the header. Structure Definition typedef struct node *node_ptr; struct node element_type element; node_ptr next; Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 29

; typedef node_ptr list; typedef node_ptr position; Empty list with header Function to test whether a linked list is empty The function is_empty () makes the L->next ( L is the header) to point to null in case the list is empty. int is_empty ( ) return list_head -> next == null; Function to test whether current position is the last in a linked list This function accepts a position p in the list and checks whether the position is the last position in the list. It returns TRUE if the p->next =NULL. int is_last( ) return ( list_head -> next == null); Find routine The find() returns the position of a given element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 30

advanced to the next position until P=NULL. In case if there is a match, the position of the element is returned. template < class Etype > int list < E type > :: find ( const Etype & x) node * p; for ( p= list_head -> next ; p! = Null; p = p-> next) if ( p-> Element == x ) current_pos = p; return 1; return 0; Deletion routine for linked lists To delete an element from the list, the position of the previous element is obtained by calling the findprevious() function. The necessary pointer changes are made as shown in the figure. The element is removed from the list and the memory allocated to the element is freed. (deallocated) template < class Etype > int list <Etype> :: Remove ( cont Etype & x ) node * cell_to_delete; if (find_previous (x) ) cell_to_delete = current_pos -> Next current_pos -> Next = cell_to_delete -> Next Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 31

delete cell_to_delete; return 1; Return 0; Find_previous - the find routine for use with delete The find_previous() returns the position of the previous element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is advanced to the next position until p=null. In case if there is a match, the position of the previous element is returned. template < class Etype > int list < Etype > :: Find previous ( const Etype & x ) node * p; for ( p = list_head; p -> Next! = Null; p = p ->Next ) if ( p -> Next -> Element == x) current_pos = p; return 1; return 0; Insertion routine for linked lists To insert an element into the list, the position after which the element is to be inserted should be provided. To insert an element, memory is allocated using malloc. The necessary pointer changes are made as shown in the figure. template < class Etype> Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 32

int list < Etype > :: Insert ( const Etype & x ) Node * p = New node (x, current_pos -> Next ) if ( p == Null ) error ( out of space ); else current_pos -> Next = p; current_pos = current-pos -> next; With the exception of the find and find_previous routines, all other operations coded take O(1) time. This is because in all cases only a fixed number of instructions are performed, no matter how large the list is. For the find and find_previous routines, the running time is O(n) in the worst case, because the entire list might need to be traversed if the element is either not found or is last in the list. On average, the running time is O(n), because on average, half the list must be traversed. DOUBLY LINKED LIST In the singly linked list,we traverse the list in one dimension.in many application it is required to traverse a list in both direction.this 2 way traverse a list in both direction.this 2 way traverse can be realised by maintaining 2 link fields in each node instead of one.each element of a doubly linked list structure has three fields -data value -a link to its successor -a link to its predecessor The predecessor link is called left link the successor link is known as right link Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 33

Thus the traversal of the list can be in any direction. such a structure is shown in following figure: null data next ptr null data next ptr null data next ptr Head Tail INSERTION OF A NODE: To insert a node into a doubly linked list to the right of a specified node,we have to consider several case,these are as follow: 1.If the list is empty,insert a new node and make left and right link of new node to be set to nil. 2.If there is a predecessor and a successor to the given node.in such a case need to readjust link of the specified node and its successor node. It is convenient to traverse lists backwards. Add an extra field to the data structure, containing a pointer to the previous cell. The cost of this is an extra link, adds to the space requirement and also doubles the cost of insertions and deletions because there are more pointers to fix. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 34

On the other hand, it simplifies deletion, because you no longer have to refer to a key by using a pointer to the previous cell; this information is now at hand. Figure shows a doubly linked list. Structure Definition Each node contains three fields. First field is data and there are two pointers next and previous. Struct node elementtype element; ptrtonode *next,*previous; ; typedef node_ptr list; Function to check whether the list is empty or not empty. The function is_empty () makes the header->next to point to null in case if the list is int is_empty ( ) return list_head -> next == null; Function to check whether the element is in the last position This function accepts a position P in the list and checks whether the position is the last position in the list. It returns TRUE if the P->next =NULL. int is_last( ) Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 35

return ( list_head -> next == null); Find the position of the element The find() returns the position of a given element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is advanced to the next position until P=NULL. In case if there is a match, the position of the element is returned. Find the position of the previous element The findprevious() returns the position of the previous element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is advanced to the next position until P=NULL. In case if there is a match, the position of the previous element is returned. template < class Etype > int list < Etype > :: Find previous ( const Etype & x ) node * p; for ( p = list_head; p -> Next! = Null; p = p ->Next ) if ( p -> Next -> Element == x) current_pos = p; return 1; return 0; Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 36

Find the position of the next element The findnext() returns the position of the next element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is advanced to the next position until P=NULL. In case if there is a match, the position of the next element is returned. position findnext (element type x, list L) position P; P=L; while(p->next!=null && P->next->element!=x) P=P->next; return P->next; Insert an element To insert an element into the list, the position after which the element is to be inserted ahould be provided. To insert an element, memory is allocated using malloc. The necessary pointer changes are made as shown in the figure. template < class Etype> int list < Etype > :: Insert ( const Etype & x ) Node * p = New node (x, current_pos -> Next ) if ( p == Null ) error ( out of space ); else Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 37

current_pos -> Next = p; current_pos = current-pos -> next; Delete To delete an elemnt from the list, the position of the previous element is obtained by calling the findprevious() function. The necessary pointer changes are made as shown in the figure. The element is removed from the list and the memory allocated to the element is freed. (deallocated) template < class Etype > int list <Etype> :: Remove ( cont Etype & x ) node * cell_to_delete; if (find_previous (x) ) cell_to_delete = current_pos -> Next current_pos -> Next = cell_to_delete -> Next delete cell_to_delete; return 1; Return 0; Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 38

CIRCULAR LINKED LIST A popular convention is to have the last cell keep a pointer back to the first. This can be done with or without a header (if the header is present, the last cell points to it), and can also be done with doubly linked lists (the first cell's previous pointer points to the last cell). The next pointer of the last element points to the header, if the header is present. If not, it simply points to the first element. Structure Definition Each node contains two fields. Every last node points the header. Function to check whether the list is empty or not The function is_empty() makes the L->next to point to L in case if the list is empty. Function to check whether the element is in the last position This function accepts a position P in the list and checks whether the position is the last position in the list. It returns TRUE if the P->next =L. Find the position of the element The find() returns the position of a given element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is advanced to the next position until P=L, the header. In case if there is a match, the position of the element is returned Find the position of the previous element The findprevious() returns the position of the previous element in a list. It compares the value of x with each and every element in the nodes after the header. In case they do not match, the pointer is advanced to the next position until P=HEADER. In case if there is a match, the position of the previous element is returned. Insert To insert an element into the list, the position after which the element is to be inserted ahould be provided. To insert an element, memory is allocated using malloc. The necessary pointer changes are made as shown in the figure. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 39

Delete To delete an element from the list, the position of the previous element is obtained by calling the findprevious() function. The necessary pointer changes are made as shown in the figure. LINKED STACKS: The operation of adding an element to the front of a linked list is quite similar to that of pushing an element onto a stack. A stack can be accessed only through its top element, and a list can be accessed only from the pointer to its first element. Similar, the operation of removing the first element from a link list is analogous to popping a stack. In both cases the only accessible item of collection is removed from that collection, and the next item becomes immediately accessible. The First node of the list is the top of the stack. Available free memory spaces can be thought of as a finite pool of empty nodes existing initially.the most natural form from this pool to take that of a linked together by the next field in each node.this pool cannot be accessed by the programmer except through the memory allocation functions and free function.for eg:malloc function remove the first node from the list where as free return a mode to the front of the list. The list of available node is called the available list. The advantage of the list implementation of the stack is that of all stacks being used by a program can share the same available list. Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 40

When any stack needs a node,it can obtain it from the single variable list.when any stack no longer needs no node,it returns the node to that same available list.as long as the total amount of spaces needed by all stack at any onetime is less then the amount of space initially available to them all,each stack is available to grow and shrink to any size. No space has been preallocated to any single stack and stack is using the space that is does not need. ALGORITHM : struct linked_stack int info; struct linked_stack * next; PUSH : void push ( int item ) stack = ( node *) malloc (size of (node) ); stack -> info = item; stack -> next = top; top = stack; POP : void pop (* node ) node * temp; if ( top == Null ) Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 41

cout << stack empty ; temp = top free ( top ); top = top -> next; return ( temp ); Prepared by Mrs.D.Maladhy (AP/IT/RGCET) Page 42