Data Structure q data organization management and storage

  • Slides: 42
Download presentation
Data Structure q data organization, management and storage format that enables efficient access and

Data Structure q data organization, management and storage format that enables efficient access and modification. q More precisely, a collection of data values, the relationships among them, and the functions or operations that can be applied to the data.

LISTS q abstract data type that represents a countable number of ordered values q

LISTS q abstract data type that represents a countable number of ordered values q Examples – Day : (Sunday, Monday, ……, Saturday) – Card : (Ace, 2, 3, …. , King) – Letter : (a, b, c, …. . , z)

LIST ADT ∙Objects : a finite ordered set with n elements ∙연산: ▪ add_last(list,

LIST ADT ∙Objects : a finite ordered set with n elements ∙연산: ▪ add_last(list, item) : : = add the item to the last of the list ▪ add_first(list, item) : : = add the item to the first of the list ▪ add(list, pos, item) : : = add the item to the position pos of the list ▪ delete(list, pos) : : = delete the item from the position pos of the list ▪ clear(list) : : = delte all of the elements in the list ▪ replace(list, pos, item) : : = replace the element of the position pos with item ▪ is_in_list(list, item) : : = check if item is in the list ▪ get_entry(list, pos) : : = get the element of the position pos ▪ get_length(list) : : = get the length of the list ▪ is_empty(list) : : = check if the list is empty ▪ is_full(list) : : = check if the list is full ▪ display(list) : : = output all of the elements in the list

How to implement LISTS q sequential representation of ordered lists – adequate for many

How to implement LISTS q sequential representation of ordered lists – adequate for many operations including insertion or deletion of elements from a stack or queue. – operations such as insertion and deletion of arbitrary elements become expensive. q linked representation of ordered lists – successive items of a list may be placed anywhere in memory. – associated with each list element is a node which contains both a data component and a pointer, called link, to the next item in the list. data 1 node data 2 datan Ù

q Dynamically Allocated Storage – malloc and free /* <alloc. h> */ int i,

q Dynamically Allocated Storage – malloc and free /* <alloc. h> */ int i, *pi; float f, *pf; pi = (int *) malloc(sizeof(int)); pf = (float *) malloc(sizeof(float)); *pi = 1024; *pf = 3. 14; printf(“n integer = %d, a float = %fn”, *pi, *pf); free(pi); free(pf);

Singly linked lists q Linked lists representation (1) the nodes do not reside in

Singly linked lists q Linked lists representation (1) the nodes do not reside in sequential locations (2) the locations of the nodes may change on different runs ptr bat cat sat vat NULL

(ex) Insertion and Deletion in linked lists ptr bat cat sat vat NULL mat

(ex) Insertion and Deletion in linked lists ptr bat cat sat vat NULL mat ptr bat cat mat sat vat NULL

q Creation of a list typedef struct list_node *list_pointer; typedef struct list_node { char

q Creation of a list typedef struct list_node *list_pointer; typedef struct list_node { char data[4]; list_pointer link; }; list_pointer ptr = NULL; ptr = (list_pointer)malloc(sizeof (list_node)) Ÿ Ÿ Ÿ self-referential structure create a pointer to a type that does not get exist NULL: defined in stdio. h(K&RC) or stddef. h(ANSI C)

(ex) Insertion (1) Two node list ptr 10 20 NULL (2) Insert a new

(ex) Insertion (1) Two node list ptr 10 20 NULL (2) Insert a new node temp after a node : insert(&ptr, node) ptr 10 20 NULL node 50 temp

List_pointer create 2( ) { /* create a linked list with two nodes */

List_pointer create 2( ) { /* create a linked list with two nodes */ list_pointer first, second; first = (list_pointer) malloc (sizeof(list_node)); second=(list_pointer)malloc (sizeof(list_node)); second ->link=NULL; second ->data =20; first ->data=10; first ->link=second; return first; } Program 4. 2 : create a two-node list

(ex) Deletion q delete(ptr, trail, node) : delete node from the list ptr, where

(ex) Deletion q delete(ptr, trail, node) : delete node from the list ptr, where trail points to the node that precedes node (1) delete(&ptr, NULL, ptr) ptr node trail = NULL 10 50 ptr 20 NULL (a) before deletion 50 20 NULL (b) after deletion (2) delete(&ptr, ptr->link) ptr trail 10 node 50 (a) before deletion ptr 20 NULL 10 20 NULL (b) after deletion

void insert (list_pointer *ptr , list_pointer node) { /* insert a new node with

void insert (list_pointer *ptr , list_pointer node) { /* insert a new node with data =50 into the list ptr after node*/ List_pointer temp; temp=(list_pointer)malloc (sizeof(list_node)); if (IS_FULL(temp)) { fprintf(stderr, ” The memory is fulln”); exit(1); } temp -> data =50; if (*ptr) { temp -> link =node -> link; node ->link=temp; } else { temp->link =NULL; *ptr = temp; } q } Program 4. 3 simple insert into front of list

void delete(list_pointer *ptr , list-pointer trail , list-pointer node) { /* delete node from

void delete(list_pointer *ptr , list-pointer trail , list-pointer node) { /* delete node from the list , trail is the preceding node ptr is the head of the list */ if (trail) trail -> link =node -> link ; else *ptr = (*ptr) - > link ; free(node); } program 4. 4 : deletion from a list

void print_list (list_pointer ptr) { printf (“ The list contains : “ ); for

void print_list (list_pointer ptr) { printf (“ The list contains : “ ); for (; ptr = ptr - > link) Printf(“%4 d “ , ptr -> data); printf (“n”); } q program 4. 5 : Printing a list

Linked list representation of Stacks and Queues q When several stacks and queues coexisted,

Linked list representation of Stacks and Queues q When several stacks and queues coexisted, there was no efficient way to represent them sequentially, i. e. , by array. top element link. . . NULL Linked Stack front rear element link. . . Linked Queue NULL

Linked list representation of Stacks(Cont’d) #define MAX_STACKS 10 typedef struct{ int key; /* other

Linked list representation of Stacks(Cont’d) #define MAX_STACKS 10 typedef struct{ int key; /* other fields */ }element; typedef struct stack *stack_pointer; typedef struct stack{ element item; stack_pointer link; }; stack_pointer top[MAX_STACKS]; Initial Condition : top[i]=NULL, 0 <= i <= MAX_STACKS Top[i]=NULL iff the ith stack is empty IS_FULL(temp) iff the memory is full

void add (stack_pointer *top , element item) { /* add an element to the

void add (stack_pointer *top , element item) { /* add an element to the top of the stack */ stack_pointer temp = (stack_pointer)malloc (sizeof (stack)); if (IS_FULL(temp) ) { fprintf(stderr, “The memory is full n”); exit(1) ; } temp -> item =item; temp ->link =*top; *top = temp; } q Program 4. 6 : Add to a linked stack

element delete (stack_pointer *top) { /* delete an element from the stack */ stack_pointer

element delete (stack_pointer *top) { /* delete an element from the stack */ stack_pointer temp = *top; element item; if (IS_EMPTY (temp)) { fprintf(stderr , “ The stack is empty n”); exit (1); } item = temp ->item; *top = temp ->link; free(temp); return item; } Program 4. 7 : delete from a linked stack

Linked list representation of Queues(Cont’d) #define MAX_QUEUES 10 typedef struct{ int key; /* other

Linked list representation of Queues(Cont’d) #define MAX_QUEUES 10 typedef struct{ int key; /* other fields */ }element; typedef struct queue *queue_pointer; typedef struct queue{ element item; queue_pointer link; }; queue_pointer front[MAX_QUEUES], rear[MAX_QUEUES]; Initial Condition : front[i]=NULL, 0 <= i <= MAX_STACKS front[i]=NULL iff the ith stack is empty IS_FULL(temp) iff the memory is full

void addq(queue_pointer *front , queue_pointer *rear, element item) { /* add an element to

void addq(queue_pointer *front , queue_pointer *rear, element item) { /* add an element to the rear of the queue */ queue_pointer temp= (queue_pointer )malloc (sizeof (queue)); if (IS_FULL (temp)) { fprintf (stderr , “The memory is full n”); exit(1); } temp -> item = item; temp ->link =NULL; if (*front) (*rear)->link =temp; else *front =temp; *rear =temp; }Program 4. 8 : add to the rear of a linked queue

element deleteq(queue_pointer *front) { /* delete an element from the queue */ queue_pointer temp

element deleteq(queue_pointer *front) { /* delete an element from the queue */ queue_pointer temp = *front; element item; if (IS_EMPTY (*front)) { fprintf(stderr, “ The queue is empty n “); exit(1); } item = temp -> item; *front = temp->link; free (temp); return item; } program 4. 9 delete from the front of a linked queue

Polynomials q Representing polynomials as linked lists typedef struct poly_node *poly_pointer typedef struct poly_node

Polynomials q Representing polynomials as linked lists typedef struct poly_node *poly_pointer typedef struct poly_node { int coef; int expon; poly_pointer link; } poly_pointer a, b, d; coef expon link

a = 3 x 14 + 2 x 8 + 1 b = 8

a = 3 x 14 + 2 x 8 + 1 b = 8 x 14 - 3 x 10 + 10 x 6 a 3 14 2 8 1 0 Ù 8 14 -3 10 10 6 Ù b

Ex) Add two polynomials poly_pointer padd(poly_pointer a, poly_pointer b) { Poly_pointer front, rear, temp;

Ex) Add two polynomials poly_pointer padd(poly_pointer a, poly_pointer b) { Poly_pointer front, rear, temp; int sum; rear = (poly_pointer)malloc(sizeof(poly_node)); if(Is_FULL(rear)) { fprintf(stderr, “The memory is full n”); exit(1); } front = rear; while (a && b) switch (COMPARE (a->expon, b->expon)) { case -1 : /* a->expon < b->expon */ attach ( b->coef, b->expon, &rear); b = b->link; break; case 0 : /* a->expon =b->expon */ sum = a->coef +b->coef; if (sum) attach (sum, a->expon, &rear); a=a->link; b=b->link; break; case 1 : /* a-> expon > b->expon */ attach(a->coef, a->expon, &rear); a=a->link; } for( ; a; a=a->link) attach(a->coef, a->expon, &rear); for( ; b; b=b->link) attach(b->coef, b->expon, &rear); rear -> link = NULL; temp = front; front = front -> link; free(temp); return front; }

Ex) Attach a node to the end of a list void attach(float coefficient, int

Ex) Attach a node to the end of a list void attach(float coefficient, int exponent, poly_pointer *ptr) { /* create a new node with coef = coefficient and expon = exponent, attach it to the node pointed to by ptr is updated to point to this new node */ poly_pointer temp; temp = (poly_pointer)malloc(sizeof(poly_node)); if(IS_FULL(temp)) { fprintf(stderr, “The memory is fulln”); exit(1); } temp->coef = coefficient; temp->expon = exponent; (*ptr)->link = temp; *ptr = temp;

Circular list q Representing polynomials as circularly linked lists – We can free all

Circular list q Representing polynomials as circularly linked lists – We can free all the nodes more efficiently if we modify our list structure so that the link field of the last node points to the first node in the list, called circular list. – A singly linked list in which the last node has a null link is called a chain. ptr q 3 14 2 8 1 Erase a circular list in a fixed amount of time 0

ex) Erasing a polynomial void erase (poly_pointer *ptr) { /* erase the polynomial pointed

ex) Erasing a polynomial void erase (poly_pointer *ptr) { /* erase the polynomial pointed to by ptr */ poly_pointer temp; while (*ptr) { temp = *ptr; *ptr = (*ptr) ->link; free (temp); } }

ex) Erasing a circular list void cerase(poly_pointer *ptr) { /* erase the circular list

ex) Erasing a circular list void cerase(poly_pointer *ptr) { /* erase the circular list ptr */ poly_pointer temp; if (*ptr) { temp = (*ptr)->link; (*ptr)->link = avail; avail = temp; *ptr = NULL; } }

Head Node q Circular link for an empty list => head node a Zero

Head Node q Circular link for an empty list => head node a Zero polynomials a 3 14 2 3 x 14 + 2 x 8 + 1 8 1 0

Ex) Adding circularly represented polynomials poly_pointer cpadd(poly_pointer a, poly_pointer b) { poly_pointer starta, d,

Ex) Adding circularly represented polynomials poly_pointer cpadd(poly_pointer a, poly_pointer b) { poly_pointer starta, d, last d; int sum, done =FALSE; starta =a ; /* record start of a */ a = a->link; /* skip head node for a and b */ b = b->link; d = get_node(); /* get a head node for sum */ d->expon = -1 ; lastd = d; do { switch (COMPARE(a->expon, b-expon)) { case – 1 : /* a->expon < b->expon */ attach(b->coef, b->expon, &lastd); b = b->link; break; case 0 : /* a-> expon = b->expon */ if (starta == a) done = TRUE; else { sum = a->coef + b->coef; if (sum) attach(sum, a->expon, &lastd); a = a->link; b = b->link; } case 1 : /* a->expon > b->expon */ attach (a->coef, a->expon, &lastd); a=a->link; } } while (!done); lastd->link = d; return d; }

Additional list operations typedef struct list_node *list_pointer; typedef struct list_node { char data; list_pointer

Additional list operations typedef struct list_node *list_pointer; typedef struct list_node { char data; list_pointer link; }; q Operations for chains – inverting a chain : invert() – concatenate two chains : concatenate() q Operations for circulary linked lists – Suppose we insert a new node at the front of the list since we have to change the link field of the last node, we must move down to the last node. – More convenient if the name of the circular list points to the last node rather than the first.

(ex) Circular list with the name pointing to the last node (a) point to

(ex) Circular list with the name pointing to the last node (a) point to the first node x 1 x 2 xn ptr (b) point to the last node x 1 q x 2 xn ptr Insertion of a node at the front or at the rear of a circular list takes a fixed amount of time.

list_pointer invert(list_pointer lead) { /* invert the list pointed to by lead */ list_pointer

list_pointer invert(list_pointer lead) { /* invert the list pointed to by lead */ list_pointer middle, trail ; middle = NULL ; while (lead) { trail = middle ; middle = lead ; lead = lead -> link ; middle -> link = trail ; } return middle; }

list_pointer concatenate ( list_pointer ptr 1, list_point ptr 2) { /* produce a new

list_pointer concatenate ( list_pointer ptr 1, list_point ptr 2) { /* produce a new list that contains the list ptr 1 followed by the list ptr 2. The list pointed to by ptr 1 is changed permanently */ list_point temp ; if ( IS_EMPTY ( ptr 1 )) return ptr 2; else { if ( !IS_EMPTY ( ptr 2 )){ for ( temp = ptr 1; temp ->link ; temp = temp ->link ); temp ->link = ptr 2 ; } return ptr 1 ; } }

void insert_front ( list_ pointer *ptr, list_pointer node ) /* insert node at the

void insert_front ( list_ pointer *ptr, list_pointer node ) /* insert node at the front of the circular list ptr, where ptr is the last node in the list */ { if ( IS_EMPTY ( *ptr )) { /* list is empty, change ptr to point to new entrt */ *ptr = node ; node -> link = node ; } else { /* list is not empty, add new entry at front */ node ->link = ( *ptr ) -> link ; ( *ptr ) -> = node ; } }

int length ( list_pointer ptr ) { /* find the length of the circular

int length ( list_pointer ptr ) { /* find the length of the circular list ptr */ list_pointer temp ; int count = 0 ; if ( ptr ) { temp = ptr ; do { count++ ; temp = temp -> link; }while ( temp != ptr ); } return count; }

Checkpoint! q Write a function to reverse the direction of pointers in a circular

Checkpoint! q Write a function to reverse the direction of pointers in a circular list.

Doubly Linked Lists We can move easily only in the direction of the links

Doubly Linked Lists We can move easily only in the direction of the links in singly linked list. q To move in either direction, it is useful to have doubly linked lists. q typedef struct node *node_pointer; typedef struct node { node_pointer llink; element item; node_pointer rlink; } ptr = ptr->llink->rlink = ptr->rlink->llink

(ex) Doubly linked circular list llink item rlink Head Node ptr

(ex) Doubly linked circular list llink item rlink Head Node ptr

(ex) Insertion and Deletion node new node deleted

(ex) Insertion and Deletion node new node deleted

void dinsert ( node_pointer node, node_pointer newnode ) { /* insert newnode to the

void dinsert ( node_pointer node, node_pointer newnode ) { /* insert newnode to the right of node */ newnode -> llink = node ; newnode -> rlink = node -> rlink ; node -> rlink -> llink = newnode ; node -> rlink = newnode ; }

void ddelete ( node_pointer node, node_pointer deleted ) { /* delete from the doubly

void ddelete ( node_pointer node, node_pointer deleted ) { /* delete from the doubly linked list */ if ( node == deleted ) printf ( “Deletion of head node not permitted. n”) ; else { deleted ->llink -> rlink = deleted -> rlink; deleted ->rlink -> llink = deleted -> llink; free ( deleted ) ; } }