This action might not be possible to undo. Are you sure you want to continue?

BooksAudiobooksComicsSheet Music### Categories

### Categories

Scribd Selects Books

Hand-picked favorites from

our editors

our editors

Scribd Selects Audiobooks

Hand-picked favorites from

our editors

our editors

Scribd Selects Comics

Hand-picked favorites from

our editors

our editors

Scribd Selects Sheet Music

Hand-picked favorites from

our editors

our editors

Top Books

What's trending, bestsellers,

award-winners & more

award-winners & more

Top Audiobooks

What's trending, bestsellers,

award-winners & more

award-winners & more

Top Comics

What's trending, bestsellers,

award-winners & more

award-winners & more

Top Sheet Music

What's trending, bestsellers,

award-winners & more

award-winners & more

P. 1

Unit 1 DS|Views: 0|Likes: 0

Published by Balaji Narayanan

Linked list

Linked list

See more

See less

https://www.scribd.com/doc/150101140/Unit-1-DS

09/08/2015

text

original

Collection of variables, possibly of different data types, connected in various ways Data structures are used to represent the mathematical model of an ADT Ad v a n t a g e s o f u s i n g ADT’ S

-teamwork

- prototyping - modular programming approach

Linked Lists

Evolution of Linked Lists

In real time systems most often the number of elements will not be known in advance. The major drawback of an array is that the number of elements must be known in advance. Hence an alternative approach was required. This give rise to the concept called linked lists. A linear list is a linear collection of data elements called nodes, where the linear order is given by means of pointers. The key here is that every node will have two parts: first part contains the information/data and the second part contains the link/address of the next node in the list. Memory is allocated for every node when it is actually required and will be freed when not needed. What is a Structure in C? Aggregate data types built using elements of other types. Example: struct Time { int hour; int minute; int second; }; Self-referential structure Self-referential structures contain pointers within the structs that refer to another identical structure. Linked lists are the most basic self-referential structures. Linked lists allow you to have a chain of structs with related data. Graphical Representation of Linked List A graphical representation of a node will look like

1

This means that for traversing through the list we need to know the starting point always. This is achieved by having a START pointer always pointing to the first element in the list. Memory organization of a Linked List

Programmatic representation of a node typedef struct node { int iData; struct node* pNext; }node; node* pSTART = NULL; The node structure contains the data and the pointer for the next node. The address of the next node must again be of type node and hence we have a pointer to the node within node itself. Such kind of structures which refers to itself are called as Re-Directions or Self Referential Structures. Inserting a node into a list Insertion logic varies depending on where in the list the element is going to be inserted, first, middle or at the end. In all situations it is as simple as making the pointer point to different nodes and hence insertion at any place will be much faster. Steps for inserting an element in the beginning of a list 1. Create a new node 2. Make the next part of new node point to the node pointed by START 3. Make the START pointer point to new node

2

node* pNewNode = NULL. node* pTempNode = NULL. Create a new node 2. pNewNode->pNext = pSTART. pNewNode->iData = iData. } Steps for inserting an element in the middle 1.Inserting a node in the beginning of a list void add_begin(int iData) { node* pNewNode = (node*)malloc(sizeof(node)). } else 3 . if (iLoc == 1) { add_begin(iData). int iLoc) { int iPos = 1. Make the previous node point to new node Inserting a node in the middle of a list void add_Middle(int iData. pSTART = pNewNode. Make the next part of new node point to the next of previous node 3.

pNewNode = (node*)malloc(sizeof(node)). pNewNode->iData = iData. pNewNode->pNext = pTempNode->pNext. } } } Steps for inserting an element in the end 1. pTempNode->pNext != NULL && iPos < iLoc. pTempNode->pNext = pNewNode. if (iPos == iLoc) { pNewNode = (node*)malloc(sizeof(node)). pNewNode->pNext = NULL. pTempNode->pNext = pNewNode. node* pNewNode = NULL.{ for (pTempNode = pSTART. pTempNode = pTempNode->pNext). pNewNode->iData = iData. node* pTempNode = NULL. pTempNode = pTempNode->pNext. for (pTempNode = pSTART. Make the previous node point to new node Inserting a node at the end void add_End(int iData) { int iPos = 0. Create a new node 2. pTempNode->pNext != NULL. } 4 . iPos++). Make the next of new node point to NULL 3.

Store the node to be deleted in a temporary pointer 2. pTempNode != NULL. Delete the node pointed by temporary pointer Deleting a node from the middle Deleting a node at the end void delete(int iData) { node* pTempNode = NULL. for(pTempNode = pPrevNode = pSTART. 1. Again deletion logic varies depending on from where the node is getting deleted. beginning. pTempNode = pTempNode->pNext) { if (iData == pTempNode->iData) 5 . Make START point to next node in the list 3. pPrevNode = pTempNode. Store the node to be deleted in a temporary pointer 2. Delete the node pointed by temporary pointer Steps for deleting a node from the middle / end 1. middle or at the end. Make the previous node’s next point to the next of the node that is being deleted 3. node* pDelNode = NULL. node* pPrevNode = NULL.Steps for deleting a node in the beginning The next step is deleting a node from a list.

} free(pDelNode). Once allocated these blocks will be deleted from the available list. Advantages The number of elements in the linked lists need not be known in advance. The system keeps tracks of all the memory available in the system with the help of a list.value> node := node. if (pDelNode == pSTART) { pSTART = pSTART->pNext. pPrevNode->pNext = pDelNode->pNext. Once the user frees the memory again the memory will be added to the list. As and when required elements can be added to a list Insertions and deletions are much faster in a linked list as there is no physical movement of elements of a list. } } } Applications of Linked Lists A linked list is used typically in computer applications for memory allocations. A graphical representation of a circular linked list is as follows Assuming that someNode is some node in the list. Circular Linked Lists Circular linked lists are very similar to a linear list except that the last node will be pointing to the first node again instead of NULL. In general linked lists are used in almost all places whenever a collection of elements are required and when the number of elements in the collection is not known in advance.next while node not someNode 6 . This area of memory is called as the memory pool. So care should be taken while doing the traversal to avoid infinite loops. this code iterates through that list starting with someNode: Forwards node := someNode do <do something with node. As and when the user requests for memory the system allocates memory to the user from this available pool.{ pDelNode = pTempNode. Limitations Searching a list is always sequential and hence it is a time consuming operation Traversal is always possible in only one direction.

one part containing the pointer/address of next node and one part containing the pointer / address of previous node. struct node* pNext. A doubly linked list is a list in which each node will have 3 parts: one part containing the information / data. Hence inserting an element in a doubly linked list is much faster than inserting a node in an array. This limitation is overcome with the help of doubly linked lists. Memory Organization Of A Doubly Linked List Programmatic Representation of a node in Doubly Linked Lists typedef struct node { int iData. Make the next part of new node equal to START 3. In addition to the START pointer. Make the previous part of new node equal to NULL 7 . There will also be a TAIL pointer pointing to the last node in the list.prev while node not someNode Doubly Linked Lists With the linked list traversal is possible in only one direction. It is possible for us to traverse from the beginning of a list till the end or from the end of the list to the beginning. The node of a doubly linked list will have 2 pointers apart from the data.value> node := node. one for pointing to the previous element and the other for pointing to the next element in the list. struct node* pPrev. The end of the list is identified with the help of a NULL value in the next / previous parts.Backwards node := someNode do <do something with node. Steps for inserting in the beginning of a doubly linked list 1. }node. *pTAIL = NULL. node* pSTART = NULL. Create a new node 2. which contains the first node there will also be a TAIL pointer pointing to the last node in the list. Inserting an element in a doubly linked list Inserting an element in a doubly linked list involves just changing the pointers unlike arrays where every element after the inserted element needs to be shifted once.

Create a new node 2. } void addHead(int iData) { node* pNewNode = getNode(iData). pNewNode->pPrev = NULL. Make the next part of new node equal to next part of the previous node 3. Make the next part of previous node point to new node 8 . pNewNode->iData = iData. pNewNode->pNext = pSTART. Make the previous part of new node equal to previous part of next node 4. Make the previous part of the node pointed by START to new node 5. pNewNode->pNext = NULL.4. pSTART->pPrev = pNewNode. } Steps for inserting an element in the middle of a doubly linked list 1. Make START point to new node node* getNode(int iData) { node* pNewNode = (node *)malloc(sizeof(node)). pSTART = pNewNode.

Make the next part of the new node equal to NULL 3. pTempNode->pNext != NULL && iLoc < iPos. int iPos = 1. int iData) { node* pNewNode = NULL. node* pTempNode = NULL. } pTempNode->pNext = pNewNode. pTempNode = pTempNode->pNext. Make the previous part of next node point to new node void insertAt(int iLoc. iPos++). if (pTempNode->pNext != NULL) { pTempNode->pNext->pPrev = pNewNode. } else // If it is the last node { pTAIL = pNewNode. if (iLoc == 1) { addHead(iData). } } } Steps for inserting an element at the end of a doubly linked list 1.5. pNewNode->pNext = pTempNode->pNext. Make the previous part of the new node equal to TAIL 9 . if (iLoc == iPos) { pNewNode = getNode(iData). pNewNode->pPrev = pTempNode. Create a new node 2. } else { for(pTempNode = pSTART. } else { printf(“Invalid Position”).

Deletion in the beginning of a doubly linked list 1. pNewNode = getNode(iData). Make the temporary pointer point to the node to be deleted 2. Make the START point to the next node of START 10 . Make the next part of the previous node equal to new node 5. Make TAIL equal to new node void addTail(int iData) { node* pNewNode = NULL. node* pTempNode = NULL. pTail->pNext = pNewNode. } Deleting an element from a doubly linked list Deleting a node from a list is as simple as changing the links. Hence deleting a node from a list is much faster when compared to arrays. pTAIL = pNewNode.4. Like insertion the deletion logic also varies depending on from where in the list we are going to delete the node. pNewNode->pPrev = pTAIL.

Make the previous part of the next node equal to previous part of the node to be deleted 4. pDelNode = pSTART. } Deletion in the middle of a doubly linked list 1. pSTART = pSTART->pNext. } else { pSTART->pPrev = NULL. Delete the node pointed to by temporary pointer 11 . Make the previous of the next node equal to previous of the node to be deleted 4. Make the next part of the previous node equal to next of the node to be deleted 3.3. } free(pTempNode). Delete the node pointed to by temporary pointer void removeHead() { node* pDelNode = NULL. Make the temporary pointer point to the node to be deleted 2. if (pDelNode == pTAIL) // If it is the last element in the list { pTAIL = NULL.

if (iLoc == iPos) { pDelNode = pTempNode->pNext. if (pDelNode == pTAIL) { pTAIL = pTAIL->pNext. int iPos = 1. pTempNode = pTempNode->pNext. iPos++). } else { for (pTempNode = pSTART. 12 . iPos < iLoc && pTempNode->pNext != NULL. pTempNode->pNext = pDelNode->pNext.void deleteAt(int iLoc) { node* pTempNode = NULL. if (iLoc == 1) { removeHead(). node* pDelNode = NULL.

Make the TAIL equal to the previous part of the node to be deleted 4. } 13 . struct node* pDelNode = NULL. Make the temporary pointer point to the node to be deleted 2. } } } Deletion at the end of a doubly linked list 1. } free(pDelNode). Make the next part of the previous node equal to next of the node to be deleted 3. if (pSTART == NULL) { printf(“List is Empty”). Delete the node pointed to by temporary pointer void removeTail() { struct node* pTempNode = NULL.} else { pDelNode->pNext->pPrev = pTempNode.

pTempNode = pTempNode>pNext) { printf(“Data = %d\n”. pTAIL = pTAIL->pNext. } } void displayFromTail() { 14 . pTempNode = pTempNode->pNext). } free(pDelNode). if (pTAIL == NULL) { pSTART = NULL. pTempNode != NULL. void displayFromStart() { node* pTempNode = NULL.else { for (pTempNode = pSTART. pTempNode->pNext != NULL. pTempNode->pNext = NULL. pTempNode->iData). } } Traversing a doubly linked list A doubly linked list can be traversed in both directions. pDelNode = pTempNode->pNext. for(pTempNode = pSTART.

Traversal is possible in both the directions unlike a linear list where the traversal is possible in only one direction Limitations Takes up additional memory for storing the previous pointer in each node Makes the insertion and deletion logic a bit complex Stack ADT Introduction to Stacks A stack is an ordered list in which items are inserted and removed at only one end called the TOP. pTempNode = pTempNode>pPrev) { printf(“Data = %d\n”. Graphical Representation 15 . for(pTempNode = pTAIL. Advantages The number of elements in a doubly linked list need not be known in advance. This means that the last item to be added is the first item to be removed. An example for a stack is a stack of plates arranged on a table.node* pTempNode = NULL. They are the „Push‟ and the „Pop‟ operations. Hence a stack is also called as Last-InFirst-Out List or LIFO list. A Push operation inserts a value into the stack and the Pop operation retrieves the value from the stack and removes it from the stack as well. As and when required elements can be added to a list Insertions and deletions are much faster as there is no physical movement of elements of a list. } } Application of Doubly Linked Lists A doubly linked list can be used in all the places where we use a linear list if the traversal happens frequently in both the directions. pTempNode->iData). There are only 2 operations that are possible on a stack. pTempNode != NULL.

Make the top point to the new node Push Operation of a Stack 16 . Steps for the push operation 1. }node. As discussed there are only 2 operations permitted on a stack: the Push and the Pop. The difference is only in the way the data is organized. Elements are always inserted in the beginning of a stack. struct node* pNext. node* pTop = NULL. The node of a stack is very similar to the node in a list. Create a new node 2.A graphical representation of a stack is shown below: Memory Organization of a Stack The memory organization of stack is very similar to that of a linear list Programmatic representation of a stack typedef struct node { int iData. Make the new node‟s next point to the node pointed by Top 3. Push Operation A push operation is for inserting an element in to a stack.

int pop() { int iData. pTop = pNewNode. if (pTop == NULL) { iData = -1. } If you had a careful look over this code this is nothing but equal to inserting an element at the end of a list. } 17 . pNewNode->pNext = pTop. } else { pTempNode = pTop. iData = pTop->iData. Pop Operation A pop operation is basically used for retrieving a value from the stack. This also removes the element from the Stack. pNewNode->iData = iData. free(pTempNode). printf(“Stack Empty”). node* pTempNode = NULL. pTop = pTop->pNext.void push(int iData) { node* pNewNode = (node *)malloc(sizeof(node)).

return iData. } Application of Stacks 18 .

19 .

Polish notation refers to the notation in which the operator is placed before the operands. the operator is always placed after the operands. 20 . For example (A + B) * (C + D) Such kind of expressions is called as infix notation. For example the above expression can be written as *+AB+CD The idea is. whenever we write expressions in this notation. For example. the above expression can be written in Reverse Polish Notation as (A+B) * (C+D) = (AB+) * (CD+) = AB+CD+* Whenever an expression is evaluated by the system it usually performs it by means of 2 steps. First it converts any expression into prefix or postfix notation and then it evaluates the expression as it makes the job much simpler. Let us see the steps involved in the conversion (A+B)*(C+D) = (+AB)*(+CD) = *+AB+CD Reverse polish notation is exactly the opposite of polish notation i.e. parenthesis are not required for determining the priority of the expressions.Evaluation of postfix expression Evaluating Expressions In normal practice any arithmetic expression is written in such a way that the operator is placed between its operands.

b. Remove the left parenthesis 7. then a. add it to Postfix Expression 4.Converting an infix expression to postfix or prefix expression makes use of stacks extensively. b. push it to STACK 5. Pop from STACK repeatedly and add it to Postfix Expression until a left parenthesis is encountered. Scan the InfixExpression from left to right and repeat steps 3 to 6 for each element of InfixExpression until the stack is empty 3. PostFixExpression ConvertToPolishNotation(InfixExpression) { 1. Pop from STACK repeatedly and add it to Postfix expression which has the same / higher precedence than XX. If a left parenthesis is encountered. The following is the algorithm for doing this conversion. If a right parenthesis is encountered. Add XX to STACK 6. If an operand is encountered. A complete program requires a lot more than what is described in the algorithm. Exit Infix to postfix Examples Conversion of infix to postfix examples 21 . If an operator XX is encountered a. Push “(“ onto the STACK and add “)” to the end of the InfixExpression 2.

Similarly the first element inserted in the queue will be the first one that will be retrieved and hence a queue is also called as First In First Out or FIFO list. The first person in the queue will be the first person to get the service.Conversion of infix to prefix examples Queues A Queue is an ordered list in which all insertions can take place at one end called the rear and all deletions take place at the other end called the front. A real time example for a queue is people standing in a queue for billing on a shop. The two operations that are possible in a queue are Insertion and Deletion. Graphical Representation Memory Organization of a Queue 22 .

then both FRONT and REAR will be pointing to the same element. if ( pFRONT == NULL ) { //If the queue is empty pFRONT = pTempNode. }node. } 23 . 1. *pREAR = NULL. If we have only one pointer called START then for every insertion we need to traverse the complete queue as insertions are always on the end and hence will be time consuming. This is pretty much similar to a linear list representation. Create a new node 2. Steps for inserting an element into a Queue Inserting into a queue can happen only at the REAR end. But in a queue insertions and deletions are going to occur on two different ends. then make FRONT point to new node 4. When there is only one element in the queue. The first part contains the data and the second part contains the address of the next node. Make the next of new node as NULL as it is the last element always 3. struct node* pNext. one pointer is called the FRONT which will always be pointing to the first element and is used for deletions. and the other pointer called REAR which will always be pointing to the last element in the queue and is used in insertions. Otherwise make the previous node‟s next ( the node pointed by REAR is always the previous node ) point to this node 5. When the queue is empty. If the queue is empty. both FRONT and REAR will be pointing to NULL. typedef struct node { int iData. To avoid this we are going to have 2 pointers to represent a queue. Make Rear point to new node Inserting a node in a queue void QInsert(int iData) { node* pTempNode = getNode(iData).Programmatic representation of a Queue The node of a queue will have 2 parts. node* pFRONT = NULL.

node* pDelNode = NULL. if (pFRONT == NULL) { pREAR = NULL. 1. If all the nodes are deleted from the queue make the FRONT and REAR as NULL Deleting a node in a queue int QDelete() { int iData = -1. if (pFRONT == NULL) { printf(“Queue Empty”). } Steps for deleting an element from the queue The deletion is the only way through which we can retrieve values from a queue.else { pREAR->pNext = pTempNode. Along with retrieving the value this will remove the entry from the queue. } free(pTempNode). Deletions always happen in the FRONT end. } return iData. } pREAR = pTempNode. Make Front as Front‟s next 3. pFRONT = pFRONT->pNext. Delete the node pointed by temporary pointer 4. pDelNode = pFRONT. 24 . } else { iData = pFRONT->iData. Store the node pointed by FRONT in a temporary pointer 2.

which unites the properties of a queue and a stack. Implementation of Deque The push (insert/assign) and pop operation is done at both the end that is start and end of the deque. p_base and p_end to keep track of front and back of the deque. once inserted into the deque the last item pushed in may be extracted from one side (popped. and the first item pushed in may be pulled out of the other side (as in a queue). We define two pointers. Initially the base and end pointer will be pointing to NULL or 0 (zero). Initially when the deque object is created. A deque. 25 . Like the stack. The following pictures show how a deque is formed based on this change in algorithm. p_base assumes the position and p_end starts pointing to p_base. or double-ended queue is a data structure. The next and previous pointer of p_base assumes NULL or 0(zero). as in a stack). When the first node is created. items can be pushed into the deque.} Deque A Deque is a queue in which insertions and deletions can happen at both ends of a queue. both p_base and p_end would point to NULL.

- Read and print without ads
- Download to keep your version
- Edit, email or read offline

Are you sure?

This action might not be possible to undo. Are you sure you want to continue?

CANCEL

OK

You've been reading!

NO, THANKS

OK

scribd