Lists Introduction - WordPress.com · inserted or deleted at any position within a list. ... List begins at index 6 node[6] ... C function for inserting a node in a linked list:
Post on 26-Jun-2018
220 Views
Preview:
Transcript
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 1
Lists
Introduction:
Lists are particularly flexible data structures where elements can be accessed,
inserted or deleted at any position within a list. Lists can also be concatenated
together or split into sub lists.
In C, an array is considered as a list, since array is the ordered collection of
elements which use contiguous blocks of storage, they are called contiguous list.
We use the array index for accessing and manipulation of array elements.
The common operation of lists is;
1) Insert: inserts an element in the list at specified position.
2) Delete: delete the specified element.
3) Display: display the elements in the list in order.
Linked List:
Linked lists are special list of some data elements linked to one another. Each
element of the linked lists is called node, which has two parts, info part which
stores the information and pointer which points to the next elements.
Start info next Info next Info null
Figure. Singly linked lists
In singly linked list nodes have one pointer (next) pointing to the next node.
Implementation of linked list:
Linked lists can be implemented using array and dynamic variables.
1. Array implementation of linked list
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 2
In array implementation of linked list, the data structure contains the information
part where actual value in the node is stored and the next, a pointer to the next
node.
A pointer to the node is represented by an array index, i.e. a pointer is an integer
between 0 and the MAXNODES-1. The data structure is given as below:
#define MAXODES 200
struct listnode
{
int info;
int next;
};
struct listnode node [MAXNODES];
This creates a space for 200 nodes each of the node consists of info part and next
pointer as,
Info next
0
1
List1 2
3
4
5
List2 6
7 End of list 1
8
9
10 End of list 2
11
12
13
14
15
………………………….
36 10
10 5
24 1
20 7
12 3
30 -1
48 -1
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 3
Under this implementation, node[p] is used to reference pth node.info at node p is
referenced as node [p].info, and node[p].next represents the next node from
node[p]. Null is represented by -1.
An external variable is used to represent the pointer to the list. For e.g. if list1 is
external list pointer, then in above figure list1=2, which indicates the list is starting
from node[2]. node[2].info is the first data item in the list1. node[2].next is the
address (index) of the second node.
In above figure;
node[2].next =5 so node[5] is second node and node [5].info = 20is the second data
item in list1.
node[5].next=7 third node
node[7].info=30, third item
node[7].next=-1, indicates the end of list.
Similarly in the case of list2
List begins at index 6
node[6].info=12 first data item
node[6].next= 3 second node index
node[3].info=24 second data item
node[3].next = 1 third node index
node[1].info = 36 third data item
node[1].next= 10 fourth node index
node[10].info=48 fourth data item
node[10].next=-1 Null, indicates the end of list2.
In the above figure, there are two lists sharing same space for storage which is the
array of nodes in number 200. If here is space available, then a list can grow until
the nodes in the array are completely filled. If any item from a list is deleted, the
free node can be used for other lists sharing the space. Which is not possible in
contiguous list, but one drawback of linked implementation is that extra storage for
pointer is needed for each node.
How we can manage free space? Initially, all nodes are unused since no lists have yet been formed. Therefore they
must be placed on the available list. The global variable say avail is used to point
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 4
the available list. We organize that list initially as:
avail=0;
for(i=0;i<=MAXNODES-1;i++)
node[i].next=i+1;
node[MAXNODES-1].next=-1;
So the array becomes:
info next
avail 0
1
2
3
4
5
6
7
8
9
10
MAXNODES-1
So all nodes are initially linked in their natural order, so that node[i] points to node
[i+1] node [0] is first node in available list, node[1] is second node and so on.
node[MAXNODES-1].next=-1.
When a node is needed for use in a particular list, it is obtained from available list.
Which can be done C routine getnode as below.
1
2
3
4
5
6
7
8
9
10
11
……
…..
-1
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 5
int getnode ()
{
int p;
if (avail==-1)
{
printf(“Sorry!!! overflow”);
return;
}
p=avail;
avail=node[avail]
}
info next
avail 0
list1 1
2
3
4
5
6
7
p=avail; p=0;
avail=node[avail].next; /*Here, avail=2*/
If avail==-1, then no nodes are available for list. If node is available, the index of
that node is returned by getnode( ). Then the data is inserted into node and added to
list as;
void insert(int p,int x)
{
int q;
if(p==-1)
{
printf(“No insertion”);
2
25 -1
3
4
5
6
7
8
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 6
return;
}
q= getnode();
node[q].info=x;
node[q].next=node[p].next
node[p].next=q;
}
If a node is deleted, a C routine freenode accept a pointer to a node and return that
node to the available list as:
void freenode (int p)
{
node[p].next=avail;
avail=p;
return;
}
Routine for delete a node that follows node p
void delete node(int p, int*px)
{
int q;
if(p==-1||node[p].next==-1)
{
printf(“Sorry!!! No deletion”);
return;
}
q= node[p].next;
*px=node[q].info;
node[p].next=node[q].next;
freenode(q);
}
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 7
Dynamic implementation of linked list:
The limitation of array implementation is that it assumes fixed size array. If all the
array blocks are filled, the extra space for new nodes cannot be created. Also the
total memory required should be contiguous blocks of memory.
To overcome such limitations, the next method to implement linked list is
using dynamic memory allocation. For this we use self referential structures. The
data structure for linked list is now:
typedef struct listnode
{
int info;
struct listnode *next;
}node;
Now creating variable for this list structure we can use
node *header;
header is the pointer to the node. The node in this structure is as given in figure
below
info next Node structure
Creating first node: To create first node, we allocate memory required for the
node and return pointer to this node.
header= (node *) malloc(sizeof(node));
header->info= value;
header->next=NULL;
We can use function getnode to create a node as
node *getnode()
{
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 8
node *p;
p= (node*)malloc(sizeof(node));
return(p);
}
And this function can be called as:
header= getnode();
header->next=NULL;
header value NULL
Inserting a node in a linked list:
node1 node 2 node 3
header 10 30 40 null
temp
header 10 20 30 40 Null
After insertion
C function for inserting a node in a linked list:
void insert
20
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 9
{
node *temp;
int i;
temp=getnode ();
if (temp==NULL)
{
printf(“Not created node”);
return;
}
for(i=1; i<=p-1; i++)
q=q->next;
printf(“Enter data”);
scanf(“%d”,&data);
temp->info=data;
temp->next=q->next;
q->next=temp;
}
Deleting a node from linked list:
header 10 20 30 40 Null
header 10 20 40 null
After deletion
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 10
C function for deleting a node from linked list:
Void deletenode (node *q, int p)
{
node *temp;
int x,i;
for (i=0;i<=p-1;i++)
{
q=q->next;
}
temp=q->next;
q->=temp->next;
x=temp->info;
free (temp);
}
Displaying the contents of linked list:
void display (node *q)
{
if (q==NULL)
printf(“No node exists in list:”);
while (q!=NULL)
{
printf(“%d”,q->info);
q=q->next;
}
}
Double linked list (DDL):
A doubly linked list is similar to singly linear linked list, except that it links nodes
in both directions. That is, each node has pointers to its next node as well as its
previous in the list. It is also called two-way list. Following figure shows the
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 11
structure of this type.
header prev info next prev info next prev info next
Figure : A doubly linked list (DLL)
The following properties characterize the doubly linked list
1. Nodes are linked on both forward and direction i.e. each node has one
address to point to next node and another address to point to the previous.
2. Last node next pointers as well as first node previous pointer are NULL.
3. Similar to the singly LL, a head node ptr holds the address of the list.
4. Searching for a node can be done in either way, thus it is faster than SLL.
Data structure for DLL:
For DLL, the data structure is declared as a structure which contains one
information (data) field and two pointers to structures. One previous, another next
as:
typedef struct dlinklist
{
int info ;
struct dlinklist *prev;
struct dlinklist *next;
}node;
The header pointer which holds the list address is declared as
node *head;
Now, allocating space for first node and assigning address of the node to head ptr,
initially
Header =NULL; /*empty list*/
allocating space for header node,
header = (node *) malloc (sizeof(node));
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 12
which creates a list as
header
The prev and next ptr are initialized as
header->prev=NULL;
header->next=NULL;
head->info = x;
A getnode () routine is defined in this DLL as
node *getnode ()
{
node *temp;
temp= (node *)malloc(sizeof(node));
temp->prev =temp->next =NULL;
return (temp);
}
This allocates the node and sets its pointers to NULL and returns its address to
calling program.
The main operations in DLL are same as SLL, but there are more pointer exchange
than SLL in each operations.
1. Create the first node operation
void createfirst (node *ps, int value)
{
if (ps!=NULL)
{
printf(“SORRY: First node exits”);
return;
}
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 13
node *temp;
temp = getnode ();
temp->info=value;
temp->prev= temp->next=NULL;
ps=temp;
}
2. Inserting a node in position p:
void insertnode(node *ps, int ps)
{
int i;
node *temp,*q, *p=ps;
temp=getnode ()
if (temp==NULL)
{
printf ( “ Insufficient memory”);
return;
}
for(i=1;i<=pos-1;i++)
ps=ps->next;
p=p->next;
q=ps->next;
temp->next=q;
ps->next=temp;
temp->prev=ps;
q->prev=temp;
}
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 14
insert
Header
X1 X2 X3 X4
New X
temp
3. Deleting a node from DLL
int delete node (node *ps, int pos)
{
int i, value;
node *temp, *q;
for(i=1;i<=pos-1;i++)
ps=ps->next;
temp=ps->next;
q=temp->next;
ps->next=q;
q->prev=ps;
value=temp->info;
free(temp);
return value;
}
temp
This routine deletes the node indicated by the variable pos and the corresponding
memory space is released. The content of that node is returned to the calling
program.
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 15
List traversal
List traversal means to start at the beginning of the list and do some action for each
node item in the list in turn, finishing with the last item in list. Generally, traversal
of list refers the visit of each item in the content of the list as once.
We can show the traversal in linked list by displaying the content of the list
as below.
void display (node *list)
{
while(list!=NULL)
{
printf (“%d”,list->info);
list=list->next;
}
}
Which traverse the entire list and displays the content of each node in the list.
Traverse of a list is needed in each list operation.
Circular Linked List
A circular linked list is similar to singly linked list, except that pointer of its
last node holds the address of the first node. i.e. having NULL pointer in the last
node points back to first node.
header
Figure Circular Linked List
We can handle CLL by:
1. Kepping track of number of nodes in linked list using a counter.
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 16
2. Keeping track of recent visited node position using a current pointer.
3. Storing address of recently visited node by current pointer.
Creating header node in CLL
node *header;
header=getnode();
header->info=data;
header->next=header
Stack and Queue as Linked list
The limitation of array implementation of stack and queue is that, in both stack and
queue there is fixed size of array is used for holding the data items in stack and
queue. Beyond that size we can’t further insert new data items in the stack and
queue. Another deficiency of array based implementation is that if we have to
insert very few elements to the stack or queue then the size of array, rest of
allocated memory is wasted.
To overcome such limitations, we can implement stack and queue as linked
list in which a stack or a queue is a collection of nodes which are arranged in
specified rule of stack and queue. Using this scheme we will be using the memory
for new item and deallocate memory when any item is removed from the stack or
queue, dynamically in runtime.
Stack as Linked List
Data structures
Since a stack here is collection of nodes, the data structures for node is defined
similarly as in linked list.
typedef struct node
{
int info;
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 17
struct node *next;
}node;
We need a stack in which nodes are pushed into and popped from
typedef struct stack
{
node *top;
}stack;
-initially the stack contains no nodes so initialization is done as
stack *s;
s=(stack *)malloc(sizeof(stack));
s->top=NULL;
Allocating space for node
node *getnode()
{
node *temp;
temp=(node *)malloc(sizeof(node));
return temp;
}
Push operation in stack
void push(stack *sptr, node *nptr)
{
int x;
if(nptr==NULL)
printf(“Sorry!!! No node created”);
else
{
nptr=getnode();
printf(“Enter the item to push in node”);
scanf(“%d”,&x);
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 18
nptr->next=sptr->top;
nptr->item=x;
sptr->top=nptr;
}
}
Pop Operation in stack
int pop (stack *sptr)
{
int x;
node *temp;
if(sptr->top==NULL)
printf(“There is no any node in stack”);
else
{
temp=sptr->top;
sptr->top=temp->next;
x=temp->item;
free(temp);
}
return x;
}
Queue as Linked List
To implement queue as a linked list, we first declare data structures for the nodes
which are inserted into and delete from the queue. Each node is same as general
linked list node consists of information and pointer field for next node.
typedef struct node
{
int info;
struct node *next;
} node;
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 19
We need a queue in which nodes are inserted into and deleted from
typedef struct queue
{
node *front;
node *rear;
}queue;
Initially the queue is empty, for empty we set front and rear pointers hold NULL
value.
queue *q;
q=(queue *)malloc(sizeof(queue));
q->front=q->rear=NULL;
To allocate space for required node is same as in link stack.
Insert Operation
To insert the node into linked queue we use the following routine
void insertnode (queue *qp, node *np)
{
int x;
np=getnode;
if(np==NULL)
{
printf(“Sorry!! There is no sufficient memory”);
return;
}
printf(“Enter the data”);
scanf(“%d”.&x);
np->info=x;
if(qp->rear==NULL)
Data Structures & Algorithms Chapter-Lists
By Surya Bam Page 20
{
qp->front=np;
qp->rear=np;
np->next=NULL;
}
else
{
qp->rear->next=np;
qp->rear=np;
np->next=NULL;
}
}
Delete operation
If there is no node in queue in queue, both front and rear pointer will be NULL, so
we should check such condition while deleting node from queue.
If there is only one node in queue, front and rear pointer are same other than
NULL. In this case both front and rear pointer will be changed to NULL.
The routine for delete operation in linked queue will be as
int deletenode(queue *qp)
{
int x;
node *np;
if(qp->rear==NULL)
printf(“Empty queue”);
else
{
np=qp->front;
x=np->info;
qp->front=np->next;
top related