Stack is a kind of last-in-first-out linear table, it is the most basic data structure, and it has been applied in many places.
First, what is the stack
stacks are linear tables that restrict insertion and deletion only in one place . Where one end of the allowed insertions and deletions is at the end of the table, called the top of the stack, and the other end of the insert and delete is not allowed to be called the bottom of the stack (bottom). The basic operation of the stack is push (stack) and POP (out of the stack), the former equivalent to the table insert operation (Insert an element to the top of the stack), the latter is a delete operation (delete a stack top element). The stack is a last-in, first-out (LIFO) data structure, the first to be deleted is the element of the most recent compression stack. Stack is like a box, into a small box inside the equivalent of a pressure stack operation, to take out a small box is out of the stack operation, when the box is taken, the last box will be taken out first, the first put in the box will be taken out at the end, which is the latter into first out. The following is a stack:
Second, the implementation of the stack
Because the stack is a table, any method that implements the table can be used to implement the stack. There are two main ways to implement a linked list and an array.
2.1-Stack link list implementation
You can use a single-linked list to implement the stack. PUSH is implemented by inserting an element at the top of the table to implement the POP by deleting the top element of the table. The stack that is implemented by using a linked list is also called a dynamic stack . The dynamic stack has some characteristics of the linked list, that is, the elements and elements in the physical storage can be discontinuous, but the function is limited, the dynamic stack can only be inserted and deleted at the top of the stack, not in the end of the stack or the middle of the stack to insert and delete operations.
The list implementation code for the stack is as follows, and the compilation environment is win10,vs2015:
#include"stdio.h"#include"stdlib.h"#include"string.h"#include"windows.h"structStack_node {intdata; structStack_node *next;}; typedefstructStack_node *ptrtonode;typedef Ptrtonode Stack; Stack Create_stack ();voidPush_stack (Stack S,intdata);voidPop_stack (Stack s);intTop_stack (Stack s);intStack_is_empty (Stack s);intMain () {stack stack= Create_stack ();//Create a new empty stack intTop_data,i; //Press stack operation, executed 10 times for(i =0; I <Ten; i++) {push_stack (stack, i); } //stack operation, executed 1 timespop_stack (stack); //returns the value of the top element of the stackTop_data =top_stack (stack); printf ("%d\n", Top_data); System ("Pause");}/*Create an empty stack*/stack create_stack () {stack S; S= (Stack)malloc(sizeof(structStack_node)); if(S = =NULL) printf ("malloc fair!\n"); S->next =NULL; returnS;}/*PUSH Operation*/voidPush_stack (Stack S,intdata) { //Create a new node to hold the elements that are pressed into the stack, i.e. the new stack topPtrtonode Head_node = (ptrtonode)malloc(sizeof(structStack_node)); if(Head_node = =NULL) printf ("malloc fair!\n"); Head_node->data = data;//Add DataHead_node->next = s->next;//The new stack top Head_node's next pointer points to the original stack top S->nextS->next = Head_node;//S->next now points to the new stack top}/*POP Operation*/voidPop_stack (Stack s) {Ptrtonode Head_node= (Ptrtonode)malloc(sizeof(structStack_node)); if(Head_node = =NULL) printf ("malloc fair!\n"); //first determine whether the stack is empty, if the stack is empty, you can no longer stack operation, error if(Stack_is_empty (s)) {printf ("error! Stack is empty!\n"); } Else{Head_node= s->next;//Head_node for the top of the stackS->next = head_node->next;//S->next points to Head_node->next, which is the new stack top Free(Head_node);//frees the memory of the original stack top element }}/*view top of stack elements*/intTop_stack (Stack s) {if(Stack_is_empty (s)) {printf ("error! Stack is empty!\n"); return 0; } Else { returnS->next->data; }}/*determine if the stack is empty*/intStack_is_empty (Stack s) {returnS->next = =NULL;}
View Code
The program presses the number 1-9 separately, then performs a stack operation, and finally prints the top element of the stack, with a result of 8.
Array implementations of 2.2 stacks
Also, stacks can be implemented using arrays. Stacks implemented using arrays are called static stacks .
Using an array to implement the stack is very simple, each stack has a topofstack to represent the top of the stack in the array subscript, for the empty stack, the value is 1 (this is the initialization of the empty stack). When you need to press the stack, you only need to add topofstack plus 1, and then the array in the value of the subscript at the bottom of the stack value can be, the stack operation is more simple, only need to topofstack minus 1. It is important to note that the POP operation on the empty stack and the PUSH operation on the full stack will result in an array out of bounds and cause the program to crash.
The array implementation of the stack is as follows, and the compilation environment is win10,vs2015:
#include"stdio.h"#include"stdlib.h"#include"string.h"#include"windows.h"#defineMinstacksize 5#defineEmptyTOS-1structStack_array {intcapacity;//capacity of the stack intTop_of_stack;//Subscript at the top of the stack int*array;//array to hold the stack};typedefstructStack_array *arrayrecord;typedef Arrayrecord Stack; Stack Create_stack (intstack_capacity);voidMake_empty (Stack s);voidPush_stack (Stack S,intdata);intTop_stack (Stack s);voidPop_stack (Stack s);intStack_is_empty (Stack s);intstack_is_full (Stack s);intMain () {stack stack= Create_stack ( -); intTopdata, I; for(i =0; I <Ten; i++) {push_stack (stack, i); } pop_stack (stack); Pop_stack (stack); Topdata=top_stack (stack); printf ("%d\n", Topdata); System ("Pause");}/*Create a stack*/Stack Create_stack (intstack_capacity) {Stack S; if(Stack_capacity <minstacksize) printf ("error! Stack size is too small!\n"); S= (Stack)malloc(sizeof(structStack_array)); if(S = =NULL) printf ("malloc error!\n"); S->array = (int*)malloc(sizeof(structStack_array) *stack_capacity); if(S->array = =NULL) printf ("malloc error!\n"); S->capacity =stack_capacity; Make_empty (S); returnS;}/*Create an empty stack*/voidMake_empty (Stack s) {//The subscript for the top of the stack is-1 indicates that the stack is emptyS->top_of_stack =Emptytos;}/*PUSH Operation*/voidPush_stack (Stack S,intdata) { if(Stack_is_full (s)) {printf ("error! Stack is full!\n"); } Else{s->top_of_stack++; S->array[s->top_of_stack] =data; }}/*POP Operation*/voidPop_stack (Stack s) {if(Stack_is_empty (s)) {printf ("error! Stack is empty!\n"); } Else{s->top_of_stack--; }}/*returns the top element of the stack*/intTop_stack (Stack s) {if(Stack_is_empty (s)) {printf ("error! Stack is empty!\n"); return 0; } Else { returnS->array[s->Top_of_stack]; }}/*check whether the stack is empty stack*/intStack_is_empty (Stack s) {//The subscript for the top of the stack is-1 indicates that the stack is empty returnS->top_of_stack = =Emptytos;}/*detects if the stack is full stack*/intstack_is_full (Stack s) {//The subscript for the top of the stack is capacity-1, and the stack is full (array subscript starting from 0) returnS->top_of_stack = =--s->capacity;}
View Code
The program presses the number 1-9 separately, then performs two out-of-stack operations, and finally prints the top element of the stack, resulting in 7.
The advantages and disadvantages of the 2.3-stack linked list implementation and array implementation
Using a linked list to implement the stack, the memory is allocated dynamically, you do not have to worry about memory allocation problems, but malloc and free call overhead is relatively large.
Using an array implementation of the stack, you need to declare the size of an array in advance, if the array size is not enough, the array may be out of bounds, if the array is too large, it will waste a certain amount of space. In general, an array is declared to be large enough to not waste too much space. In addition to this problem, the execution of stacks implemented with arrays is much more efficient than a linked list.
In both implementations, the operations of the stack, such as PUSH and POP, are run in constant time, and execution is fast, so the stack is usually very efficient to execute.
Third, the application of the stack
Stacks are widely used in functions such as function invocation, interrupt processing, expression evaluation, memory allocation, and so on. This article next describes the application of stacks in function calls:
Suppose you have a function f (), and now the function f () calls the function g (), and the function g () needs to call function H (). When function f () starts calling function g (), all local variables of function f () need to be stored by the system, otherwise the new function called G () will overwrite the variable that calls the function f (), and the current position of the keynote function needs to be preserved. So that when the function is executed, it knows where to go and then executes the calling function. Similarly, when function g () calls the function h (), information about G () needs to be stored as well. After the completion of the function H (), and then remove the information from the system function g () and then execute the function g (); When the function g () is completed, the information about the function f () is removed from the system and then the function f () is executed. As can be seen from the description here, the function call, the call function information is stored in a last-in-first-out structure, obviously, with the stack to store it again good, with a picture to illustrate:
Resources:
The third edition of the introduction to algorithms
"Data structure and algorithm analysis--c language description"
Basic data structure--detailed stack