0% found this document useful (0 votes)
18 views110 pages

DS Unit1

The document provides an overview of linked lists, including their structure, types (simple, circular, doubly, and circular doubly linked lists), and operations such as creation, traversal, searching, insertion, and deletion of nodes. It explains how linked lists differ from arrays, emphasizing their non-contiguous memory allocation and flexibility in data structure implementation. Additionally, algorithms for various linked list operations are included, detailing the processes for managing nodes effectively.

Uploaded by

nanisudheer274
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views110 pages

DS Unit1

The document provides an overview of linked lists, including their structure, types (simple, circular, doubly, and circular doubly linked lists), and operations such as creation, traversal, searching, insertion, and deletion of nodes. It explains how linked lists differ from arrays, emphasizing their non-contiguous memory allocation and flexibility in data structure implementation. Additionally, algorithms for various linked list operations are included, detailing the processes for managing nodes effectively.

Uploaded by

nanisudheer274
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 110

UNIT-1

Linked Lists

A B C 

Head

• A linked list is a series of connected nodes


• Each node contains at least
– A piece of data (any type)
– Pointer to the next node in the list
• Head: pointer to the first node node
• The last node points to NULL A

dat pointe
a r
linked lists

1. Concepts of linked lists


2.Simple linked lists
3.Circular linked lists
4.Double linked lists
5.Circular double linked lists
1. Concepts of linked list
• A linked list is a linear collection of data elements
called nodes in which linear representation is given by
links from one node to the next node.
• Similar to array, it is a linear collection of data
elements of the same type.
• Different from array, data elements of linked list are
generally not lined in consecutive memory space;
instead they are dispersed in various locations
Concepts of linked list
• Linked list is a data structure which in turn can be
used to implement other data structures. Thus, it acts
as building block to implement data structures like
stacks, queues and their variations.
• A linked list can be perceived as a train or a sequence
of nodes in which each node contains one or more
data fields and a pointer to the next node.
Element of linked list
• Linked list element (node) is user defined structure
data type, typically contains two parts
 data variables
 pointers to next elements, hold the addresses of
next elements

Example:

struct node {
int data; // data
struct node *next; // pointer to next element
};
Simple Linked List
START

1 2 3 4 5 6 7 X

• In the above linked list, every node contains two parts - one
integer and the other a pointer to the next node.
• The data part of the node which contains data may include a
simple data type, an array or a structure.
• The pointer part of the node contains a pointer to the next node
(or address of the next node in sequence).
• The last node will have no next node connected to it, so it will
store a NULL value.
• A linked list is defined by the pointer pointing to the first node,
e.g START
Linked List Operations
1. Create a node and linked list
2. Traversal, e.g. display all elements
3. Search node
4. Insert node
at beginning, at end, after/before a node
5. Delete node
at beginning, at end, after/before a node
6. Sort
How to create nodes
A node is a structure data type, can be created in
two methods, statically and dynamically.
•Static method
– use array of structures
– declared as globally outside functions
– declared locally within a function

•Dynamic method (mostly used for linked list)


– use stdlib function malloc(size) get memory space
struct node *np = (struct node*) malloc(sizeof(struct node));
How to create nodes
struct node *np = (struct node*) malloc(sizeof(struct node));

At run time, OS allocates consecutive sizeof(struct node)


bytes in the heap region,
return the address of the address of the first memory cell,

store the address to struct node type pointer np.


Need (struct node*) to cast the return address to struct
node pointer value.

Need use free(np) to release when deleting the node!!!


Otherwise cause memory leaking
Traversing Linked Lists
• We can traverse the entire linked list using a
single pointer variable called START.

• The START node contains the address of the first


node; the next part of the first node in turn
stores the address of its succeeding node.

• Using this technique the individual nodes of the


list will form a chain of nodes.

• If START = NULL, this means that the linked list is


empty and contains no nodes.
2. Singly Linked Lists
• A singly linked list is the simplest type of linked list in which
every node contains some data and a pointer to the next node
of the same data type.
START

1 2 3 4 5 6 7 X

Example:

struct node {
int data;
struct node *next;
};
Traversal Singly Linked Lists
ALGORITHM FOR TRAVERSING A LINKED LIST

Step 1:
[INITIALIZE] SET PTR = START
Step 2:
Repeat Steps 3 and 4 while PTR != NULL
Step 3:
Apply Process to PTR->DATA
Step 4:
SET PTR = PTR->NEXT
[END OF LOOP]
Step 5: EXIT

void display(struct node *ptr) {


while(ptr != NULL) {
printf("%d ", ptr->data); // process
ptr = ptr->next;
}
}
Call as display(START);
Searching for Val 4 in Linked List

1 7 3 4 2 6 5 X

PTR

1 7 3 4 2 6 5 X

PTR

1 7 3 4 2 6 5 X

PTR

1 7 3 4 2 6 5 X

PTR

How to search an element in a Linked List?


Need to traverse the entire Linked List and compare each node with
the data to be search and continue until a match is found.
search process from the first node as random access is not possible
in a Linked List.
• 1) At the front of the linked list
2) After a given node.
3) At the end of the linked list.
Add a node at the front: (4 steps process)
• The new node is always added before the head of the
given Linked List.
• And newly added node becomes the new head of the
Linked List.
• For example, if the given Linked List is 10->15->20->25
and we add an item 5 at the front, then the Linked List
becomes 5->10->15->20->25. Let us call the function
that adds at the front of the list is push().
• The push() must receive a pointer to the head pointer,
because push must change the head pointer to point to
the new node
• /* Given a reference (pointer to pointer) to the head of a list
• and an int, inserts a new node on the front of the list. */
• void push(struct Node** head_ref, int new_data)
• {
• /* 1. allocate node */
• struct Node* new_node = (struct Node*)
malloc(sizeof(struct Node));
• /* 2. put in the data */
• new_node->data = new_data;
• /* 3. Make next of new node as head */
• new_node->next = (*head_ref);
• /* 4. move the head to point to the new node */
• (*head_ref) = new_node;
• }
Add a node after a given node: (5 steps process)
We are given a pointer to a node, and the new node is
inserted after the given node.
• /* Given a node prev_node, insert a new node after the given
• prev_node */
• void insertAfter(struct Node* prev_node, int new_data)
• {
• /*1. check if the given prev_node is NULL */
• if (prev_node == NULL)
• {
• printf("the given previous node cannot be NULL");
• return;
• }
• /* 2. allocate new node */
• struct Node* new_node =(struct Node*) malloc(sizeof(struct Node));
• /* 3. put in the data */
• new_node->data = new_data;
• /* 4. Make next of new node as next of prev_node */
• new_node->next = prev_node->next;
• /* 5. move the next of prev_node as new_node */
• prev_node->next = new_node;
• }
Add a node at the end: (6 steps
process)
• The new node is always added after the last node
of the given Linked List. For example if the given
Linked List is 5->10->15->20->25 and we add an
item 30 at the end, then the Linked List becomes 5-
>10->15->20->25->30.

Since a Linked List is typically represented by the
head of it, we have to traverse the list till the end
and then change the next to last node to a new
node.
• /* Given a reference (pointer to pointer) to the head
• of a list and an int, appends a new node at the end */
• void append(struct Node** head_ref, int new_data)
• {
• /* 1. allocate node */
• struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
• struct Node *last = *head_ref; /* used in step 5*/
• /* 2. put in the data */
• new_node->data = new_data;
• /* 3. This new node is going to be the last node, so make next
• of it as NULL*/
• new_node->next = NULL;
• /* 4. If the Linked List is empty, then make the new node as head */
• if (*head_ref == NULL)
• {
• *head_ref = new_node;
• return;
• }
• /* 5. Else traverse till the last node */
• while (last->next != NULL)
• last = last->next;
• /* 6. Change the next of last node */
• last->next = new_node;
• return; }
Searching a Linked List
ALGORITHM TO SEARCH A LINKED LIST
Step 1: [INITIALIZE] SET PTR = START
Step 2: Repeat Step 3 while PTR != NULL
Step 3: IF VAL = PTR->DATA
SET POS = PTR
Go To Step 5
ELSE
SET PTR = PTR->NEXT
[END OF IF]
[END OF LOOP]
Step 4: SET POS = NULL // not found
Step 5: EXIT // found, output POS

struct node* search(struct node *ptr, int num) {


while((ptr != NULL) && (ptr->data != num)) {
ptr = ptr->next;
}
return ptr;
}
// call example, search(START, 4)
To delete a node from the linked list,
we need to do the following steps
• To delete a node from the linked list, we need
to do the following steps.
1) Find the previous node of the node to be
deleted.
2) Change the next of the previous node.
3) Free memory for the node to be deleted.
Deleting the First Node
Algorithm to delete the first node from the linked
list

Step 1: IF START = NULL, then


Write UNDERFLOW
Go to Step 5
[END OF IF]
Step 2: SET PTR = START
Step 3: SET START = START->NEXT
Step 4: FREE PTR
Step 5: EXIT
1 7 3 4 2 6 5 X

START

7 3 4 2 6 5 X

START
• void deleteNode(struct node **head, int key) { //temp
is used to freeing the memory
struct node *temp; //key found on the head node.
//move to head node to the next and free the head.
if(*head->data == key)
{
temp = *head; //backup the head to free its memory
*head = (*head)->next;
free(temp); }
}
Deleting the Last Node
1 7 3 4 2 6 5 X

START, PREPTR, PTR

1 7 3 4 2 6 X 5 X

PREPTR PTR
START

ALGORITHM TO DELETE THE LAST NODE OF THE LINKED LIST


Step 1: IF START = NULL, then
Write UNDERFLOW
Go to Step 8
[END OF IF]
Step 2: SET PTR = START
Step 3: Repeat Steps 4 and 5 while PTR->NEXT != NULL
Step 4: SET PREPTR = PTR
Step 5: SET PTR = PTR->NEXT
[END OF LOOP]
Step 6: SET PREPTR->NEXT = NULL
Step 7: FREE PTR
Step 8: EXIT
1. Make the current node points to the head node. (current => data = 10).
2. current => next. (current=>next=>data = 20).
3. current => next => next. (current=>next=>next=>data = 30).
4. We have to remove the node 20. Since current => next = 20 we can
remove the node by setting current => next = current =>next => next. And
then free the node.
5. Finally, the new linked list.
Deleting the Node After a Given Node

1 7 3 4 2 6 5 X

START, PREPTR, PTR

1 7 3 4 2 6 5 X

START PREPTR PTR

1 7 3 4 2 6 5 X

START

1 7 3 4 6 5 X
Deleting the Node After a Given Node
ALGORITHM TO DELETE THE NODE AFTER A GIVEN NODE FROM THE
LINKED LIST

Step 1: IF START = NULL, then


Write UNDERFLOW
Go to Step 10
[END OF IF]
Step 2: SET PTR = START
Step 3: SET PREPTR = PTR
Step 4: Repeat Step 5 and 6 while PRETR->DATA != NUM
Step 5: SET PREPTR = PTR
Step 6: SET PTR = PTR->NEXT
[END OF LOOP]
Step7: SET TEMP = PTR->NEXT
Step 8: SET PREPTR->NEXT = TEMP->NEXT
Step 9: FREE TEMP
Step 10: EXIT
3. Circular Linked List
• In a circular linked list, the last node contains a pointer to the first
node of the list. We can have a circular singly listed list as well as
circular doubly linked list. While traversing a circular linked list,
we can begin at any node and traverse the list in any direction
forward or backward until we reach the same node where we
had started. Thus, a circular linked list has no beginning and no
ending.

START

1 2 3 4 5 6 7
4. Doubly Linked List
 A doubly linked list or a two way linked list is a more complex
type of linked list which contains a pointer to the next as well
as previous node in the sequence. Therefore, it consists of
three parts and not just two. The three parts are data, a
pointer to the next node and a pointer to the previous node

START

X 1 1 2 3 4 X
5. Circular Doubly Linked List
• A circular doubly linked list or a circular two way linked list is
a more complex type of linked list which contains a pointer to
the next as well as previous node in the sequence.

• The difference between a doubly linked and a circular doubly


linked list is same as that exists between a singly linked list
and a circular linked list. The circular doubly linked list does
not contain NULL in the previous field of the first node and
the next field of the last node. Rather, the next field of the
last node stores the address of the first node of the list, i.e;
START. Similarly, the previous field of the first field stores the
address of the last node.
Circular Doubly Linked List
• Since a circular doubly linked list contains three parts in its
structure, it calls for more space per node and for more
expensive basic operations. However, it provides the ease to
manipulate the elements of the list as it maintains pointers to
nodes in both the directions . The main advantage of using a
circular doubly linked list is that it makes searches twice as
efficient.

START

1 1 2 3 4
Array Implementation
Stack using linked list

Stack using an array - drawback


• If we implement the stack using an array, we need to
specify the array size at the beginning(at compile
time).
• We can't change the size of an array at runtime. So, it
will only work for a fixed number of elements.
Solution
• We can implement the stack using the linked list.
• In the linked list, we can change its size at runtime.
``
Example: Suppose we are converting 3*3/(4-1)+6*2 expression
into postfix form.
Balancing Symbols
• To check that every right brace, bracket, and
parentheses must correspond to its left counterpart
– e.g. [( )] is legal, but [( ] ) is illegal
• Algorithm
(1) Make an empty stack.
(2) Read characters until end of file
i. If the character is an opening symbol, push it onto the stack
ii. If it is a closing symbol, then if the stack is empty, report an
error
iii. Otherwise, pop the stack. If the symbol popped is not the
corresponding opening symbol, then report an error
(3) At end of file, if the stack is not empty, report an error
Postfix Expressions
• Calculate 4.99 * 1.06 + 5.99 + 6.99 * 1.06
– Need to know the precedence rules
• Postfix (reverse Polish) expression
– 4.99 1.06 * 5.99 + 6.99 1.06 * +
• Use stack to evaluate postfix expressions
– When a number is seen, it is pushed onto the stack
– When an operator is seen, the operator is applied to the 2 numbers
that are popped from the stack. The result is pushed onto the stack
• Example
– evaluate 6 5 2 3 + 8 * + 3 + *
• The time to evaluate a postfix expression is O(N)
– processing each element in the input consists of stack operations and
thus takes constant time

You might also like