DS (U1)
DS (U1)
UNIT-I
Data structures
Data structures can be classified based on the organization and the operations defined on
it.
DATA STRUCTURES II IT
UNIT-I
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
Data is a set of elementary items. The possible ways in which the data items are logically related
The programs have to follow a certain rules to access and process the structure data. And so ,
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
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
STACK
A stack is an ordered collection of data items.
But these insertion (PUSH) and deletion (POP) operation can be done only at one end
called the top of the stack.
B C
Rear
and items can be inserted at the rear of the queue. i.e.,
Front
B C D
Rear
The first element inserted into a queue is the first element to be removed. For this reason, a
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.
Example LEVEL
0
A
B C 1
D E F G 2
H I J 3
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.
2 3
4
DATA STRUCTURES II IT
UNIT-I
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 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
DATA STRUCTURES II IT
UNIT-I
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.
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:
DATA STRUCTURES II IT
UNIT-I
Empty Operation:
Empty stack contains no elements can be initialized by -1 i.e., s.top = -1.
Implementation:
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
DATA STRUCTURES II IT
UNIT-I
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]
Return(S[TOP + 1])
Implementation
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
DATA STRUCTURES II IT
UNIT-I
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.
2. Increment the top pointer.
3. Push the element onto the top of the stack
ALGORITHM:
Variables used:
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);
DATA STRUCTURES II IT
UNIT-I
}
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.
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
DATA STRUCTURES II IT
UNIT-I
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.
DATA STRUCTURES II IT
UNIT-I
(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
DATA STRUCTURES II IT
UNIT-I
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.
DATA STRUCTURES II IT
UNIT-I
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:
- 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
DATA STRUCTURES II IT
UNIT-I
3 6
5 5 15
15
Read D Read E Read / Read- Read+ Read \0
2
8 8 4
d by Page 17
6 . D.Mal
6 hy6(AP RGCE
2 17
15 15 15 15
DATA STRUCTURES II IT
UNIT-I
* 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
FIG(1) FIG(2)
DATA STRUCTURES II IT
UNIT-I
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.
It is assumed that an available area of storage for this node structure consists of a stack of
available nodes,as shown below:
AVAIL
.
.
.
DATA STRUCTURES II IT
UNIT-I
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.
Return(NEW)
Step 1:
FIRST 20 30 40 NULL
NEW
Step 2:
FIRST 20 30 40 NULL
NEW 10
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
DATA STRUCTURES II IT
UNIT-I
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:
FIRST 20 30 40 NULL
NEW
Step 2:
FIRST 20 30 40 NULL
NEW 25
SAVE
Step 3:
25 FIRST 20 30 40 NULL
SAVE
Step 4:
FIRST 20 25 30 40 NULL
Step 2:
FIRST 20 30 40 NULL
NEW 50 NULL
SAVE
Step 3:
FIRST 20 30 40
NEW 50 NULL
SAVE
Step 4:
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.
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,
DATA STRUCTURES II IT
UNIT-I
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
DATA STRUCTURES II IT
UNIT-I
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
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.
DATA STRUCTURES II IT
UNIT-I
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.
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.
DATA STRUCTURES II IT
UNIT-I
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.
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 node_ptr list;
typedef node_ptr position;
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
DATA STRUCTURES II IT
UNIT-I
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;
}
delete cell_to_delete;
return 1;
}
Return 0;
}
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.
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
DATA STRUCTURES II IT
UNIT-I
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.
DATA STRUCTURES II IT
UNIT-I
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;
int is_empty ( )
{
return list_head -> next == null;
}
int is_last( )
{
DATA STRUCTURES II IT
UNIT-I
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.
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.
DATA STRUCTURES II IT
UNIT-I
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.
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 )
{
DATA STRUCTURES II IT
UNIT-I