Data structure - implementation of sequential stack and chain stack

Table of contents

1. Concept

1. Definition of stack

2. Top of stack

3. Bottom of the stack

2. Interface

1. Writable interface

1) Data is pushed onto the stack

2) Data popping

3) Clear the stack

2. Read-only interface

1) Get the top data of the stack

2) Get the number of stack elements

3) Stack empty judgment

3. Basic operations of stack

4. Implementation of Sequential Stack

1. Data structure definition

2. Create a stack

3. Clear the stack

4. Determine whether the stack is empty

5. Determine whether the stack is saturated

6. Push into the stack

7. Get out of the stack

8. Get the top element of the stack

9. Release the memory requested by malloc

Example of printing all elements in the stack

5. Linked list implementation of stack

1. Data structure definition

2. Create a stack

3. Clear the stack

4. Determine whether the stack is empty

5. Push into the stack

6. Pop out

7. Get the top element of the stack

8. Release the memory requested by malloc

Example of printing all elements in the stack

6. Advantages and Disadvantages of Two Implementations

1. Sequence table implementation

2. Linked list implementation


1. Concept

1. Definition of stack

  A stack  is  a linear list where insertions  and  deletions  are  limited  to  the end of the list . The stack  is also called a Last In First Out (Last In First Out) linear list, or LIFO for short.
  

2. Top of stack

  The stack  is a linear list, and we   call the end that  allows insertion  and  deletion the top of the stack .

3. Bottom of the stack

  Opposite  to the top of the stack  , the other end is called  the bottom of the stack . In fact, we don't need to care about the elements at the bottom of the stack.

2. Interface

1. Writable interface

1) Data is pushed onto the stack

  The insertion operation of the stack is called  pushing , which can also be called pushing or pushing. As shown in the figure below, it represents three push operations:

2) Data popping

  The deletion operation of the stack is called  stack popping. As shown in the figure below, it represents two pop operations:
Insert image description here

3) Clear the stack

  Keep  popping the stack until the stack is empty, as shown in the following figure:

2. Read-only interface

1) Get the top data of the stack

  For a stack, only  the top  data can be obtained, and other data is generally not supported.

2) Get the number of stack elements

  The number of stack elements is generally stored in an extra variable, which is incremented by one when pushed onto the stack  and decremented by one when popped out of the stack  . In this way, there is no need to traverse the entire stack when obtaining stack elements. Obtain the number of stack elements with a time complexity of �(1)O(1).

3) Stack empty judgment

  When the number of stack elements is zero, it is an empty stack. Pop operations are not allowed on an empty  stack  .

3. Basic operations of stack

Create an empty stack: CreateStack (len)

Clear stack: ClearStack (S)

Determine whether the stack is empty: EmptyStack (S)

Determine whether the stack is full: FullStack (S)

Push elements onto the stack: PushStack (S,x)

Element pop: PopStack (S)

Get the top element of the stack: GetTop (S)

4. Implementation of Sequential Stack

1. Data structure definition

For the sequence table, which is represented as an array in C language  ,  before defining the stack  , we need to consider the following points:
  1) The storage method of stack data, and the data type of stack data;
  2) The size of the stack;
  3) stack top pointer;

  • We can define a  stack structure ,  and  the C language implementation is as follows:
typedef int datatype;
typedef struct node{     /*定义栈中数据元素的数据类型*/
	datatype *data;      /*用指针指向栈的存储空间*/
	int maxlen;          /*当前栈的最大元素个数*/
	int top;             /*指示栈顶位置(数组下标)的变量*/
}sqstack;                /*顺序栈类型定义*/

2. Create a stack

The C language implementation is as follows:

sqstack* stack_create(int len)
{
	sqstack *s;

	if((s=(sqstack *)malloc(sizeof(sqstack)))==NULL)
	{
		puts("malloc failed");
		return NULL;
	}
	if((s->data=(datatype *)malloc(len*sizeof(datatype)))==NULL)
		
	{
		puts("malloc failed");
		return NULL;
	}
	s->maxlen=len;
	s->top=-1;

	return s;
}

3. Clear the stack

The C language implementation is as follows:

void stack_clear(sqstack* s)
{
	s->top = -1;
}

4. Determine whether the stack is empty

The C language implementation is as follows:

int stack_empty(sqstack* s)
{
	return (s->top==-1 ? 1:0);
}

5. Determine whether the stack is saturated

The C language implementation is as follows:

int stack_full(sqstack* s)
{
	return (s->top==(s->maxlen-1) ? 1:0);
}

6. Push into the stack

The C language implementation is as follows:

int stack_push(sqstack* s,datatype value)
{
	if(s->top==s->maxlen-1){
		puts("stack is full");
		return -1;
	}

	s->data[s->top+1]=value;
	s->top++;

	return 1;
}

7. Get out of the stack

The C language implementation is as follows:

datatype stack_pop(sqstack* s)
{
	s->top--;
	return s->data[s->top+1];
}

8. Get the top element of the stack

The C language implementation is as follows:

datatype stack_top(sqstack* s)
{
	return(s->data[s->top]);
}

9. Release the memory requested by malloc

The C language implementation is as follows:

void stack_free(sqstack *s)
{
	free(s->data);
	s->data=NULL;

	free(s);
	s=NULL;
}

Example of printing all elements in the stack

The C language implementation is as follows:

sqstack.h

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;

typedef struct node{
	datatype *data;
	int maxlen;
	int top;
}sqstack;

extern sqstack* stack_create(int len);
extern int stack_empty(sqstack* s);
extern int stack_full(sqstack* s);
extern void stack_clear(sqstack* s);
extern int stack_push(sqstack* s,datatype value);
extern datatype stack_pop(sqstack* s);
extern datatype stack_top(sqstack* s);
extern void stack_free(sqstack *s);

#endif

sqstack.c

#include "sqstack.h"

sqstack* stack_create(int len)
{
	sqstack *s;

	if((s=(sqstack *)malloc(sizeof(sqstack)))==NULL)
	{
		puts("malloc failed");
		return NULL;
	}
	if((s->data=(datatype *)malloc(len*sizeof(datatype)))==NULL)
		
	{
		puts("malloc failed");
		return NULL;
	}
	s->maxlen=len;
	s->top=-1;

	return s;
}

int stack_empty(sqstack* s)
{
	return (s->top==-1 ? 1:0);
}
int stack_full(sqstack* s)
{
	return (s->top==(s->maxlen-1) ? 1:0);
}
void stack_clear(sqstack* s)
{
	s->top = -1;
}
int stack_push(sqstack* s,datatype value)
{
	if(s->top==s->maxlen-1){
		puts("stack is full");
		return -1;
	}

	s->data[s->top+1]=value;
	s->top++;

	return 1;
}
datatype stack_pop(sqstack* s)
{
	s->top--;
	return s->data[s->top+1];
}
datatype stack_top(sqstack* s)
{
	return(s->data[s->top]);
}
void stack_free(sqstack *s)
{
	free(s->data);
	s->data=NULL;

	free(s);
	s=NULL;
}

test.c

#include "sqstack.h"

int main(int argc, const char *argv[])
{
	sqstack *s;
	int n=5;

	s=stack_create(n);

	stack_push(s,10);
	stack_push(s,20);
	stack_push(s,30);
	stack_push(s,40);
	stack_push(s,50);
	stack_push(s,60);
	
	while(!stack_empty(s))
	{
		printf("%d ",stack_pop(s));
	}
	putchar(10);

	stack_clear(s);
	stack_free(s);

	return 0;
}

Makefile

CC = gcc
CFLAGS =  -g -Wall

test:test.o sqstack.o
	$(CC) $(CFLAGS) -o $@ $^

.PHONY:clean
clean:
	rm  test *.o

-g: Generates the necessary symbol information for the symbolic debugging tool (GNU's gdb). If we want to debug the source code, we must add this option.

-Wall: Indicates that all useful alarm information of gcc is allowed to be issued

-c: Just compile without linking, and generate the target file ".o "

-o test: means outputting the output file to file

operation result:

5. Linked list implementation of stack

1. Data structure definition

For linked lists,  before defining the stack  , we need to consider the following points:
  1) The storage method of stack data and the data type of stack data;
  2) The size of the stack;
  3) The top pointer of the stack;

We can define a  stack structure ,  and  the C language implementation is as follows:

typedef int datatype;

typedef struct node{
	datatype data;
	struct node* next;
}listnode,*linklist;

2. Create a stack

The C language implementation is as follows:

linklist stack_create()
{
	linklist s;

	if((s=(linklist)malloc(sizeof(listnode)))==NULL){
		puts("malloc failed");
		return NULL;
	}
	s->next=NULL;

	return s;
}

3. Clear the stack

The C language implementation is as follows:

void stack_clear(linklist s)
{
	linklist p;

	printf("clear:");
	p=s->next;
	while(p)
	{
		s->next=p->next;
		printf("%d ",p->data);
		free(p);
		p=s->next;
	}
	putchar(10);
}

4. Determine whether the stack is empty

The C language implementation is as follows:

int stack_empty(linklist s)
{
	return (s->next==NULL ? 1:0);
}

5. Push into the stack

The C language implementation is as follows:

int stack_push(linklist s,datatype value)
{
	linklist p;
	if((p=(linklist)malloc(sizeof(listnode)))==NULL)
	{
		puts("malloc failed");
		return -1;
	}

	p->data = value;
	p->next=s->next;
	s->next = p;

	return 0;
}

6. Pop out

The C language implementation is as follows:

datatype stack_pop(linklist s)
{
	linklist p;
	datatype ret;

	p=s->next;
	s->next=p->next;
	ret=p->data;

	free(p);
	p=NULL;

	return ret;
}

7. Get the top element of the stack

The C language implementation is as follows:

datatype stack_top(linklist s)
{
	return (s->next->data);
}

8. Release the memory requested by malloc

The C language implementation is as follows:

void stack_free(linklist s)
{
	linklist p;

	printf("free:");
	p=s;
	while(p)
	{
		s=s->next;
		printf("%d ",p->data);
		free(p);
		p=s;
	}
	putchar(10);

}

Example of printing all elements in the stack

The C language implementation is as follows:

linkstack.h        

#ifndef __LINKLIST_H__
#define __LINKLIST_H__

#include <stdio.h>
#include <stdlib.h>
typedef int datatype;

typedef struct node{
	datatype data;
	struct node* next;
}listnode,*linklist;

extern linklist stack_create();
extern int stack_empty(linklist s);
extern void stack_clear(linklist s);
extern int stack_push(linklist s,datatype value);
extern datatype stack_pop(linklist s);
extern datatype stack_top(linklist s);
extern void stack_free(linklist s);

#endif

linkstack.c

#include "linkstack.h"

linklist stack_create()
{
	linklist s;

	if((s=(linklist)malloc(sizeof(listnode)))==NULL){
		puts("malloc failed");
		return NULL;
	}
	s->next=NULL;

	return s;
}
int stack_empty(linklist s)
{
	return (s->next==NULL ? 1:0);
}


int stack_push(linklist s,datatype value)
{
	linklist p;
	if((p=(linklist)malloc(sizeof(listnode)))==NULL)
	{
		puts("malloc failed");
		return -1;
	}

	p->data = value;
	p->next=s->next;
	s->next = p;

	return 0;
}

datatype stack_pop(linklist s)
{
	linklist p;
	datatype ret;

	p=s->next;
	s->next=p->next;
	ret=p->data;

	free(p);
	p=NULL;

	return ret;
}

datatype stack_top(linklist s)
{
	return (s->next->data);
}

void stack_clear(linklist s)
{
	linklist p;

	printf("clear:");
	p=s->next;
	while(p)
	{
		s->next=p->next;
		printf("%d ",p->data);
		free(p);
		p=s->next;
	}
	putchar(10);
}
void stack_free(linklist s)
{
	linklist p;

	printf("free:");
	p=s;
	while(p)
	{
		s=s->next;
		printf("%d ",p->data);
		free(p);
		p=s;
	}
	putchar(10);

}

test.c

#include "linkstack.h"

int main(int argc, const char *argv[])
{
	linklist s;
	
	s=stack_create();

	stack_push(s,10);
	stack_push(s,20);
	stack_push(s,30);
	stack_push(s,40);
	stack_push(s,50);
	stack_push(s,60);
	
#if 0
	while(!stack_empty(s))
	{
		printf("%d ",stack_pop(s));
	}
	putchar(10);
#endif
//	stack_clear(s);
	stack_free(s);
	return 0;
}

Makefile

CC = gcc
CFLAGS =  -g -Wall

test:test.o linkstack.o
	$(CC) $(CFLAGS) -o $@ $^

.PHONY:clean
clean:
	rm  test *.o

operation result:

6. Advantages and Disadvantages of Two Implementations

1. Sequence table implementation

  When using a sequence table to implement a stack,  the constant time complexity of  pushing  and  popping the stack is low, and the stack clearing operation can be O(1)  compared to  the linked list implementation  . The only shortcoming is that it needs to apply for space in advance, and When the space is not enough, expansion is required. The expansion method is not mentioned in this article. You can refer to the article: "100 C/C++ Interview Examples" (4) Vector expansion strategy .

2. Linked list implementation

  When using a linked list to implement a stack, the constant time complexity of pushing  and  popping the stack  is slightly higher. The main reason is that every time a stack element is inserted, space needs to be applied for, and every time a stack element is deleted, space needs to be released, and the  stack clearing  operation is O(n ), directly  setting the top pointer of the stack  to empty will cause a memory leak. The advantage is: there is no need to pre-allocate space, and within the allowed memory range, it can be  pushed onto the stack without any restrictions on the sequence table.

Guess you like

Origin blog.csdn.net/m0_74712453/article/details/135288533