0% found this document useful (0 votes)
30 views30 pages

Best Stack and Queue

stac and queue

Uploaded by

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

Best Stack and Queue

stac and queue

Uploaded by

mk1139418
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
Data Structures UNIT-2 Stack & Queue Data Structures 13. Stack A stack is_an Abstract Data Type (ADT), commonly used in most programming languages. It is named stack as it behaves like a real-world stack, for example ~ a deck of cards or a pile of plates, etc. ‘A real-world stack allows operations at one end only. For example, we can place or remove a card or plate from the top of the stack only. Likewise, Stack ADT allows all data operations at one end only, At any given time, we can only access the top element of a stack. This feature makes it LIFO data structure. LIFO stands for Last-in-first-out. Here, the element which is placed (inserted or added) last, is accessed first. In stack terminology, insertion operation is called PUSH operation and removal operation is called POP operation. Stack Representation The following diagram depicts a stack and its operations — 2, Last In - First Out Push Pop ‘Data Boment sta Element ‘Bata Element ‘Data Element ata Bement ata Element ‘Data Bement ata Bement ata Dement ata Eomont Stack Stack A stack can be implemented by means of Array, Structure, Pointer, and Linked List. Stack can either be a fixed size one or it may have a sense of dynamic resizing. Here, we are going to Implement stack using arrays, which makes it a fixed size stack implementation. 60 Data Structures Basic Operations Stack operations may involve initializing the stack, using it and then de-initializing it. Apart from these basic stuffs, a stack is used for the following two primary operations — + push() ~ Pushing (storing) an element on the stack. * pop() — Removing (accessing) an element from the stack. When data is PUSHed onto stack. To use a stack efficiently, we need to check the status of stack as well, For the same purpose, the following functionality is added to stacks — * peek() — get the top data element of the stack, without removing it. + isFull() ~ check if stack is full + isEmpty() ~ check if stack is empty. At all times, we maintain a pointer to the last PUSHed data on the stack. As this pointer always represents the top of the stack, hence named top. The top pointer provides top value of the stack without actually removing it First we should learn about procedures to support stack functions - peek() Algorithm of peek() function begin procedure peek return etack{top] end procedure Implementation of peek() function in C programming language — int peak() { return stack(top]; 61 Data Structures isfull() Algorithm of isfull() function - begin procedure isfull Sf top equals to MAXSIZE return true else return false endif end procedure Implementation of isfull() function in C programming language ~ bool isfull() { if(top == MAXSIZE) return true; else return fale; isempty() Algorithm of isempty() function — begin procedure isenpty if top Less than 2 return true else return faise endif end procedure 62 Data Structures Implementation of isempty() function in C programming language is slightly different. We initialize top at -1, as the index in array starts from 0. So we check if the top is below zero or -1 to determine if the stack is empty. Here's the code — bool isenpty() { a) return tru S¢(top alse return false; Push Operation The process of putting a new data element onto stack is known as a Push Operation. Push operation involves a series of steps — # Step 1 — Checks if the stack is full. + Step 2 — If the stack is full, produces an error and exit. + Step 3 ~ If the stack is not full, increments top to point next empty space. + Step 4 — Adds data element to the stack location, where top is pointing + Step 5 — Returns success. E Push Operation top —— 63 Data Structures If the linked list is used to implement the stack, then in step 3, we need to allocate space dynamically. Algorithm for PUSH Operation ‘A simple algorithm for Push operation can be derived as follows — begin procedure push: stack, data if stack is full return null endif top + top +1 stack[top] + data end procedure Implementation of this algorithm in C, is very easy. See the following code — void push(int data) { sf(IdeFULL()) { top = top + 3; stack[top] = deta; jelse { print#("could not insert data, Stack is full.\n"); Pop Operation Accessing the content while removing it from the stack, is known as a Pop Operation. In an array implementation of pop() operation, the data element is not actually removed, instead top is decremented to a lower position in the stack to point to the next value. But in linked-list implementation, pop() actually removes data element and deallocates memory space. A Pop operation may involve the following steps — + Step 1 - Checks if the stack is empty. + Step 2 ~ if the stack is empty, produces an error and exit. 64 Data Structures + Step 3 ~ If the stack is not empty, accesses the data element at which top is pointing + Step 4 — Decreases the value of top by 1. + Step 5 — Returns success, Pop Operation Stack Algorithm for Pop Operation A simple algorithm for Pop operation can be derived as follows — begin procedure pop: stack Af stack is empty retuen null endif data « stack{top] top + top - 2 return data fend procedure 6 Data Structures Implementation of this algorithm in C, is as follows — ine pop(int data) { if(lisempty()) { data = stack{top]; top = top - 2; return dat jelse { printf("Could not retrieve data, Stack is empty.\n")3 } For a complete stack program in C programming language, please click here, Stack Program in C We shall see the stack implementation in C programming language here. You can try the program by clicking on the Try-it button. To learn the theory aspect of stacks, click on visit previous page. Implementation in C #include int naxsize int steck{8]; int top = -15 int isempty() { if(top == -1) return 43 else return 85 66 Data Structures int isfull() ( Sf(top == MAXSIZE) return 15 else return 85 > int peek() { return stack[top]; > nt pop) { int datas if(Lisempty()) { data = stack{top]; top = top - 2 return di jeise { printf("Could not retrieve data, Stack is empty.\n"); int push(int data) { af(1isfuldQ) ¢ top = top +45 stack [top] date; }else { printf("could not insert data, Stack is full. \n"); 67 Data Structures int main() { 1/ push stens on to the stack push(3); push(5)5 push(3) 5 push(2) 5 push(12)3 push(35); print#(“Elenent at top of the stack: %d\n" ,peek()); print#("Elements: \n"); // print stack data whdle(lisempty()) { int data = pop(); printf("%d\n", data); print#("Stack full: s\n" , isfull()?"true":"felse"); 'False"); printf("stack empty: s\n" , isempty()?"tru return 95 If we compile and run the above program, it will produce the following result — Elenent at top of the stack: 15 Elenents: 6 n 1 ° 5 3 stack full: false [Stack empty: true t 68 Data Structures 15. Queue Queue is an abstract data structure, somewhat similar to Stacks. Unlike stacks, a queue iS open at both its ends. One end is always used to insert data (enqueue) and the other is used to remove data (dequeue). Queue follows First-In-First-Qut methodology, i.e., the data item stored first will be accessed first. stn FRSTIN .astour aS FIRST OUT A real-world example of queue can be a single-lane one-way road, where the vehicle enters first, exits first, More real-world examples can be seen as queues at the ticket windows and bus-stops. Queue Representation ‘As we now understand that in queue, we access both ends for different reasons. The following diagram given below tries to explain queue representation as data structure - _ = =a In Data Data Data Data Data Data ‘Out a Last in Last out Firat in Fret Out Queue As in stacks, a queue can also be implemented using Arrays, Linked-lists, Pointers and Structures. For the sake of simplicity, we shall implement queues using one-dimensional array, Basic Operations Queue operations may involve initializing or defining the queue, utilizing it, and then completely erasing it from the memory. Here we shall try to understand the basic operations associated with queues ~ + enqueue() ~ add (store) an item to the queue. + dequeue() — remove (access) an item from the queue. 69 Data Structures Few more functions are required to make the above-mentioned queue operation efficient. These are — + peek() — Gets the element at the front of the queue without removing It. isfull() — Checks if the queue is full isempty() ~ Checks if the queue is empty. In queue, we always dequeue (or access) data, pointed by front pointer and while enqueing (or storing) data in the queue we take help of rear pointer. Let's first learn about supportive functions of a queue — peek() This function helps to see the data at the front of the queue. The algorithm of peek() function is as follows — begin procedure peek return queue[front] end procedure Implementation of peek() function in C programming language — int peek() { return queue[front]; } isfull() ‘As we are using single dimension array to implement queue, we just check for the rear pointer to reach at MAXSIZE to determine that the queue Is full. In case we maintain the Queue in a circular linked-list, the algorithm will differ. Algorithm of isfull() function — begin procedure isfull Lf pear equals to MAXSIZE return true else 70 Data Structures Feturn false enaif end procedure Implementation of isfull() function in C programming language ~ boot isfull() { if(rear == MAXSIZE - 1) return true; else return false; isempty() Algorithm of isempty() function — begin procedure isempty if front is lees than MIN OR front dz greater than rear return true alse return False endif fend procedure If the value of front is less than MIN or 0, it tells that the queue is not yet initialized, hence empty. Here's the C programming code — bool isempty() ¢ if(front < @ || front > rear) return true; else return false; 71 Data Structures Enqueue Operation Queues maintain two data pointers, front and rear. Therefore, its operations are comparatively difficult to implement than that of stacks. The following steps should be taken to enqueue (insert) data into a queue — + Step 1 ~ Check if the queue is full + Step 2 — If the queue is full, produce overfiow error and exit. + Step 3 - If the queue is not full, increment rear pointer to point the next empty space. + Step 4 - Add data element to the queue location, where the rear is pointing. + Step 5 — Return success. Rear Front nN ¢ 8 A before Rear Front t+ to. D c 8 A after Queue Enqueue Sometimes, we also check to see if a queue is initialized or not, to handle any unforeseen situations. 72 Data Structures Algorithm for enqueue Operation procedure enqueue (data) if queue is full return overflow endif rear e rear +2 queve[rear] = data return true fend procedure Implementation of enqueue() in C programming language — int enqueue(int data) if(istullQ) return 95 rear = rear + 15 queuefrear] = data; return 2; end procedure Dequeue Operation ‘Accessing data from the queue is a process of two tasks — access the data where front is pointing and remove the data after access, The following steps are taken to perform dequeue operation - + Step 1 - Check if the queue is empty. + Step 2 — If the queue is empty, produce underflow error and exit. + Step 3 — If the queue is not empty, access the data where front is pointing. + Step 4 — Increment front pointer to point to the next available data element. + Step 5 — Return success. 73 Data Structures Rear Front tea 4 betore (Ee) Ee 8 A Rear Front ————— after > c 8 , Queue Queue Dequeue Algorithm for dequeue Operation procedure dequeue if queue is empty return underflow end if data = queve(front] front © front +1 return true end procedure Implementation of dequeue() in C programming language — Ant dequeve() { if (isempty()) return 8; int data = queue[front]; front = front + 13 return dates 74 Data Structures Queue Program in C We shall see the stack implementation in C programming language here. You can try the program by clicking on the Try-it button. To learn the theory aspect of stacks, click on visit previous page. Implementation in C #include include #include include define MAX 6 int intarray[Mex]; int front = @; int re Pe oa int itencount = @; int peek(){ return intarray[ front]; bool istmpty(){ return itemcount == 0; } bool isFull(C return dtemcount == MAX; int size(){ return itencount; void insert (int data){ AF(ISFULLO) 75 Data Structures iF(rear 4){ rear = -15 intAray[++rear] = data; Atemcounts+; int renovedata(){ int data = intarray[fronte+]; iF (Front Front ? itencount--; Max) 8 retuen data; int main() { /* insert 5 Stems */ insert(3)5, insert(5); insert(9) 5 Ansere(a); insert(32)5 1) Front + 8 I) rear We Uf index: 01234 We df queue: 3592 12 insert (15); Uf Front + @ Uf rear: 5 76 Data Structures ie Jf index 202234 5 53592215 if (4sFuLLOM print#("queue is full!\n"); U/ venove one item int nun = removeData(); print#("Elenent removed: %d\n", num) ; UI Front: 1 df vear 3 5 Ue a Uf index 21234 5 We - J/ queue : 5921215 I) insert nore items insert(16); I) front: 1 J vear uw Uf index 2 @12345// J/ queue : 185911215 J/ As queue is full, elements will not be inserted. insert(17)3 insert(28); We Uf index 2 @22345 // 7 Data Structures // queue : 16 5 91 12 15 print#(“Elenent at Front: fe\n".peek())s printf ( \n" e\n" printf("index : 54.322 5 printe(” = \n"); print #("Queve while(!istmpty())4 int n = renovepata(); printf("xd *5n)3 If we compile and run the above program, it will produce the following result — Qqueve is full! Element renoved: 3 Element at front: 5 index: 543220 Qqueve: $9112 15 16 78 Data Structures Hash Table Hash Table is a data structure which stores data in an associative manner. In a hash table, data is stored in an array format, where each data value has its own unique index value, Access of data becomes very fast if we know the index of the desired data. Thus, it becomes a data structure in which insertion and search operations are very fast irrespective of the size of the data. Hash Table uses an array as a storage medium and uses hash technique to generate an index where an element is to be inserted or is to be located from. Hashing Hashing is a technique to convert a range of key values into a range of indexes of an array. We're going to use modulo operator to get a range of key values. Consider an example of hash table of size 20, and the following items are to be stored. Item are in the (key, value) format. (=n EO + (1,20) + (2,70) + (42,80) + (4,25) + (12,44) © (14,32) + a7an + (13,78) + (37,98) 79 Data Structures Sr.No. Key Hash ‘Array Index T T T%20=1 x z z 2% 20=2 z 3 co) 42% 20 = z z z 4% 20=4 a 3 iz 12% 20= 12 1 6 cry 14% 20= 14 cry 7 7 17% 20= 17 7 z 3 13% 20= 15 is 3 7 37% 20= 17 7 Linear Probing As we can see, it may happen that the hashing technique is used to create an already used index of the array. In such 2 case, we can search the next empty location in the array by looking into the next cell until we find an empty cell. This technique is called linear probing. ‘After Linear Sr.No. key Hash Array Index | Probing, Array Index T T T%20=1 T T zi 2 2% 20=2 2 2 3 a AZO =2 z 3 4 a 4% 20-4 q 4 5 iz 12% 20= 12 TZ iz 6 7 14% 20= 14 17 7 80 Data Structures 7 7 17% 20= 17 7 7 3 ri 13% 20 = 13 1s Ts 3 7 37% 20 = 17 17 is Basic Operations Following are the basic primary operations of a hash table, + Search ~ Searches an element in a hash table. + Insert ~ inserts an element in a hash table. + Delete ~ Deletes an element from a hash table, Data Item Define a data item having some data and key, based on which the search is to be conducted in a hash table. struct Dataltem { int data; int keys i Hash Method Define @ hashing method to compute the hash code of the key of the data item, int hashCode(int key)( return key % SIZE; Search Operation Whenever an element is to be searched, compute the hash code of the key passed and locate the element using that hash code as index in the array. Use linear probing to get the element ahead if the element is not found at the computed hash code, 81 Data Structures struct Datalten *search(int key){ //gst the hash int hashIndex = hashCode(key) //move in erray until an empty while(hazhaeray[hashindex) [= NULL) At(hashanray[hachindex]->key == key) retuen hashArray [hashIndex]; (qo to next cell sthachindex; (Jweap around the table hashIndex %= SIZE; return NULL Insert Operation Whenever an element is to be inserted, compute the hash code of the key passed and locate the index using that hash code as an index in the array. Use linear probing for empty location, if an element is found at the computed hash code. void insert (int key,int data){ struct DataTtem ‘item = (struct Datatten*) malloc(sizeof(struct Datartem)); iten->data = data; tem->key = key; //gt the hash int hashIndex = hashCode(key); //move in array until an enpty or deleted cell while(hasharray[hashindex] 2)t l= NULL && hacharray[hashtndex)->key I= //g0 to next cell +hashIndex; 82 Data Structures ‘/Iwrap around the table hashIndex R= SIZES hasharray[hashIndex] = item; Delete Operation Whenever an element is to be deleted, compute the hash code of the key passed and locate the index using that hash code as an index in the array. Use linear probing to get the element ahead if an element is not found at the computed hash code. When found, store a dummy item there to keep the performance of the hash table intact. struct Datatten* delete(struct Datatten* item){ Int key = item->key; //get the hash int hashIndex = hashCode(key) ; //move in array until an empty white(hasharray[hashindex] !=MULL){ LF (hasharray[hashIndex]->key == key)( struct DataTtem* temp = hashArray[hashIndex]; I/assign a dunmy item at deleted position hashArray[hashindex] = cummyltems return temp; } 11go to next cell tthashIndex; /Twrap around the table hashindex = SIze; } return NULL; 83 Data Structures Hash Table Program in C Hash Table is a data structure which stores data in an associative manner. In hash table, the data is stored in an array format where each data value has its own unique index value. Access of data becomes very fast, if we know the index of the desired data. Implementation in C Hinelude cetdio.h> #include Winclude by struct Datartem { int data; int keys hb struct Datalten* hasharray(SIZE]; struct DataItem* dunnyTtem; struct Datalten” iten; int hashCode(int key){ return key % SIZE5 struct Datalten “search(int key){ //get the hash int hashtndex shcode key) 5 J/move in array until an enpty while(hashArray[hashIndex] I= NULL){ i#(hashdrray[hashindex]->key return hashArray [hashindex]; key) 84 Data Structures //g0 to next cell shashIndex; {Jura around the table hashIndex %= SIZE return NULLS void insert(int key,int data){ struct DataTtem titem = (struct Datertent) malloc(sizeof(struct Daterten)); item-rdata = dete; stem->key = key; //get the hash int hashtndex = hashcode(key); [/move in array until an empty or deleted cell while (hashArray[hashindex] MULL 8& hashAeray[hashIndex]-skey I= -1){ Hig to next cell +thashIndex; /Iwrap around the table hashindex X= StZe; hasharray[hashIndex] = item; struct Datatten* delete(struct Datalten* item){ int key = iten=>key; //get the hash 85 Data Structures int hashIndex = hashCode( key); J/move in array until an empty while(hasharray[hashindex] != NULL){ key){ struct Datattem* temp = hashArray[hashIndex]; if(hashArray [hashIndex]->key //assign a dummy item et deleted position hashArray[hashIndex] = dummyltem; return temp; Hgo to next cell +hashindex; /Iwrap around the table hashIndex %= SIZE; return NULLS void display(){ int 2 = 95 for(i = 0; ieStZe; 44) ( Lf(hashanray[1] = NULL) printf (" (%d,%d)", hasharray[i]->key,hasharray[i]->data); else printe(t a~ printf(*\n")3 86 Data Structures int main(){ dunmyrten = (struct Datalten) malloc(sizeof(struct, Datattem)); durmyitem-rdata = -1; dunmyTten=>key = -15 insert(1, 20); insert(2, 78) insert(42, 88); insert(4, 25); insert(12, 44) insert(14, 32); insert(27, 11); insert (13, 78); insert (37, 9795, display); Stem = search(37); Ae(dtem t= NULL)E printf("Elenent found: %d\n", iten- odata); else { print#("Element not found\n"); delete (item); item = eearch(37); Sf (item [= NULL){ printf("Elenent found: d\n" ddata); else { » item printf("Element not found\s 25 87 Data Structures If we compile and run the above program, it will produce the following result — m~ (4,28) (2,78) (42,80) (4,25) me me eee me (22,44) (93,78) (44,32) ~~ ~~ (47,21) (37,97) ~~ Elenent found: 97 Elenant not found 88

You might also like