Data Structure: Basic operations and Applications of Stack
1 Basic knowledge
1.1 Introduction
Similar to sequential table or link list, stack is another kind of linear storage structure. Stack is special due to its unique features:
- The stack can only access data from one end of the list, and the other end is closed.
- The elements follows the rules ’ First in last out '.
1.2 Implement the stack
There are two ways to implement the stack, usually we call them Sequential Stack and Link Stack. It is easy to inform that the sequential stack uses array to store elements while the link stack uses link list. The only difference between two ways is the place where we put the elements in the physical space.
2 Operations of Sequential Stack
2.1 Push the element
// Push 'elem' into the stack
int push(int* a,int top,int elem){
a[++top]=elem;
return top;
}
2.2 Pop the element
// Pop 'elem' out of the stack
int pop(int * a,int top){
if (top==-1) {
printf("Empty stack");
return -1;
}
printf("Pop element:%d\n",a[top]);
top--;
return top;
}
2.3 Check the code
int main() {
int a[100];
int top=-1;
top=push(a, top, 1);
top=push(a, top, 2);
top=push(a, top, 3);
top=push(a, top, 4);
top=pop(a, top);
top=pop(a, top);
top=pop(a, top);
top=pop(a, top);
top=pop(a, top);
return 0;
}
Output, we can see it works well:
3 Operations of Link Stack
3.1 Push the element
We can also use link list to implement the stack, the definition and construction is same to that of link list:
typedef struct lineStack{
int data;
struct lineStack * next;
}lineStack;
For each element, we insert it behind the head node:
lineStack* push(lineStack * stack,int a){
lineStack * line=(lineStack*)malloc(sizeof(lineStack)); // Create new node
line->data=a;
line->next=stack; // Connect the new node and the head node
stack=line; // Alter the head node's directivity
return stack;
}
3.2 Pop the element
The pop operation is just the same:
lineStack * pop(lineStack * stack){
if (stack) {
lineStack * p=stack;
stack=stack->next;
printf("Pop element:%d ",p->data);
if (stack) {
printf("The element on the top:%d\n",stack->data);
}else{
printf("The stack is empty\n");
}
free(p);
}else{
printf("No element in the stack");
return stack;
}
return stack;
}
3.3 Check the code
int main() {
lineStack * stack=NULL;
stack=push(stack, 1);
stack=push(stack, 2);
stack=push(stack, 3);
stack=push(stack, 4);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
stack=pop(stack);
return 0;
}
Output:
4 Applications
4.1 Number system conversion
Request:The user provides the data to be converted and the base of the data, the base converter should provides the user with the final correct conversion result.
The converter can convert the number among 2(Binary system) to 36:
Thinking:
- When the user input the number, we store it in a sequential structure(string array).
- Convert the number to decimal system than convert to the number system they need. The final result will be stored in a stack.
Code implementation:
#include <stdio.h>
#include <string.h>
#include <math.h>
int top=-1; // We use -1 to represent the top of the stack
void push(char *a, char elem){
a[++top]=elem;
}
void pop(char *a){
if(top==-1){
return;
}
if(a[top]>=10){
printf("%c",a[top]+55);
}else{
printf("%d",a[top]);
}
top--;
}
// Transform all types of number to decimal system
int scaleFun(char * data,int system){
int k=(int)strlen(data)-1;
int system_10_data=0;
int i;
for(i=k;i>=0;i--){
int temp;
if (data[i]>=48 && data[i]<=57) {
temp=data[i]-48;
}else{
temp=data[i]-55;
}
system_10_data+=temp*pow(system, k-i);
}
return system_10_data;
}
int main() {
char data[100];
printf("The number system input(2-36):");
int system;
scanf("%d",&system);
getchar();
printf("The number to be converted:");
scanf("%s",data);
getchar();
int system_10_data=scaleFun(data, system);
printf("The number system output:");
int newSystem;
scanf("%d",&newSystem);
getchar();
while (system_10_data/newSystem) {
push(data,system_10_data%newSystem );
system_10_data/=newSystem;
}
push(data,system_10_data%newSystem);
printf("Result:\n");
while (top!=-1) {
pop(data);
}
}
Example output:
4.2 Parentheses matching
Request: Give a series of the parentheses to determine whether they match, for example, {([])} match but {(}[ do not.
Thinking:
- If we meet ( or { , push it
- If we meet ) or } , match with the top element, if they match, pop them, else we would say the parentheses do not match.
Code implementation:
/* Parentheses matching */
#include <stdio.h>
#include <string.h>
int top=-1;
void push(char * a,int elem){
a[++top]=elem;
}
void pop(char* a){
if (top==-1) {
return ;
}
top--;
}
char visit(char * a){
// If the stack is empty, return NULL
if (top!=-1) {
return a[top];
}else{
return ' ';
}
}
int main() {
char a[30];
char bracket[100];
printf("Input the parentheses:");
scanf("%s",bracket);
getchar();
int length=(int)strlen(bracket);
for (int i=0; i<length; i++) {
if (bracket[i]=='('||bracket[i]=='{') {
push(a, bracket[i]);
}else{
if (bracket[i]==')') {
if (visit(a)=='(') {
pop(a);
}else{
printf("Not match");
return 0;
}
}else{
if (visit(a)=='{') {
pop(a);
}else{
printf("Not match");
return 0;
}
}
}
}
// If they all match, the stack will be empty in the end
if (top!=-1) {
printf("Not match");
}else{
printf("Match");
}
}
Output: