+ All Categories
Home > Documents > Lists Introduction - WordPress.com · inserted or deleted at any position within a list. ... List...

Lists Introduction - WordPress.com · inserted or deleted at any position within a list. ... List...

Date post: 26-Jun-2018
Category:
Upload: dinhcong
View: 220 times
Download: 0 times
Share this document with a friend
21
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
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;

Data Structures & Algorithms Chapter-Lists

By Surya Bam Page 21

if(qp->front==NULL)

qp->rear=NULL;

free(np);

}

return x;

}

Displaying the data in the queue

void display (queue *qp)

{

node *np;

if(qp==NULL)

printf(“Empty queue”);

else

{

np=qp->front;

while(np!=NULL)

{

printf(“%d”,np->info);

np=np->next;

}

}

}


Recommended