Inhaltsverzeichnis
1. Beschreibbare Schnittstelle
1) Daten werden auf den Stapel verschoben
2. Schreibgeschützte Schnittstelle
1) Holen Sie sich die obersten Daten des Stapels
2) Ermitteln Sie die Anzahl der Stapelelemente
3. Grundoperationen des Stapels
4. Implementierung des sequentiellen Stapels
1. Definition der Datenstruktur
4. Stellen Sie fest, ob der Stapel leer ist
5. Bestimmen Sie, ob der Stapel gesättigt ist
8. Holen Sie sich das oberste Element des Stapels
9. Geben Sie den von malloc angeforderten Speicher frei
Beispiel für das Drucken aller Elemente im Stapel
5. Verknüpfte Listenimplementierung des Stapels
1. Definition der Datenstruktur
4. Stellen Sie fest, ob der Stapel leer ist
7. Holen Sie sich das oberste Element des Stapels
8. Geben Sie den von malloc angeforderten Speicher frei
Beispiel für das Drucken aller Elemente im Stapel
6. Vor- und Nachteile zweier Implementierungen
1. Implementierung der Sequenztabelle
2. Implementierung einer verknüpften Liste
1. Konzept
1. Definition des Stapels
Ein Stapel ist eine lineare Liste , in der Einfügungen und Löschungen auf das Ende der Liste beschränkt sind . Der Stapel wird auch als lineare Liste Last In First Out (Last In First Out) oder kurz LIFO bezeichnet.
2. Oberseite des Stapels
Der Stapel ist eine lineare Liste, und wir nennen das Ende, das das Einfügen und Löschen ermöglicht , den oberen Teil des Stapels .
3. Unten im Stapel
Im Gegensatz zum oberen Ende des Stapels wird das andere Ende als unteres Ende des Stapels bezeichnet . Tatsächlich müssen wir uns nicht um die Elemente am unteren Ende des Stapels kümmern.
2. Schnittstelle
1. Beschreibbare Schnittstelle
1) Daten werden auf den Stapel verschoben
Der Einfügevorgang des Stapels wird als Pushing bezeichnet , was auch als Pushing oder Pushing bezeichnet werden kann. Wie in der folgenden Abbildung dargestellt, handelt es sich um drei Push-Vorgänge:
2) Daten-Popping
Der Löschvorgang des Stapels wird als Stack- Popping bezeichnet. Wie in der folgenden Abbildung dargestellt, stellt es zwei Pop-Operationen dar:
3) Räumen Sie den Stapel auf
Öffnen Sie den Stapel so lange , bis er leer ist, wie in der folgenden Abbildung dargestellt:
2. Schreibgeschützte Schnittstelle
1) Holen Sie sich die obersten Daten des Stapels
Für einen Stapel können nur die obersten Daten abgerufen werden, andere Daten werden im Allgemeinen nicht unterstützt.
2) Ermitteln Sie die Anzahl der Stapelelemente
Die Anzahl der Stapelelemente wird im Allgemeinen in einer zusätzlichen Variablen gespeichert, die um eins erhöht wird, wenn sie auf den Stapel verschoben wird, und um eins dekrementiert wird, wenn sie aus dem Stapel entnommen wird . Auf diese Weise ist es nicht erforderlich, beim Abrufen von Stapelelementen den gesamten Stapel zu durchlaufen. Ermitteln Sie die Anzahl der Stapelelemente mit einer Zeitkomplexität von �(1)O(1).
3) Stapeln Sie leere Urteile
Wenn die Anzahl der Stapelelemente Null ist, handelt es sich um einen leeren Stapel. Pop-Operationen sind auf einem leeren Stapel nicht zulässig .
3. Grundoperationen des Stapels
Erstellen Sie einen leeren Stapel: CreateStack (len)
Stapel löschen: ClearStack (S)
Bestimmen Sie, ob der Stapel leer ist: EmptyStack (S)
Bestimmen Sie, ob der Stapel voll ist: FullStack (S)
Elemente auf den Stapel schieben: PushStack (S,x)
Element-Pop: PopStack (S)
Holen Sie sich das oberste Element des Stapels: GetTop (S)
4. Implementierung des sequentiellen Stapels
1. Definition der Datenstruktur
Für die Sequenztabelle, die in der C-Sprache als Array dargestellt wird , müssen wir vor der Definition des Stapels
die folgenden Punkte berücksichtigen: 1) Die Speichermethode der Stapeldaten und der Datentyp der Stapeldaten;
2) Die Größe von der Stapel;
3) Stapeloberseitenzeiger;
- Wir können eine Stapelstruktur definieren . Die C -Sprachimplementierung lautet wie folgt:
typedef int datatype;
typedef struct node{ /*定义栈中数据元素的数据类型*/
datatype *data; /*用指针指向栈的存储空间*/
int maxlen; /*当前栈的最大元素个数*/
int top; /*指示栈顶位置(数组下标)的变量*/
}sqstack; /*顺序栈类型定义*/
2. Erstellen Sie einen Stapel
Die C-Sprachimplementierung lautet wie folgt:
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. Räumen Sie den Stapel auf
Die C-Sprachimplementierung lautet wie folgt:
void stack_clear(sqstack* s)
{
s->top = -1;
}
4. Stellen Sie fest, ob der Stapel leer ist
Die C-Sprachimplementierung lautet wie folgt:
int stack_empty(sqstack* s)
{
return (s->top==-1 ? 1:0);
}
5. Bestimmen Sie, ob der Stapel gesättigt ist
Die C-Sprachimplementierung lautet wie folgt:
int stack_full(sqstack* s)
{
return (s->top==(s->maxlen-1) ? 1:0);
}
6. In den Stapel schieben
Die C-Sprachimplementierung lautet wie folgt:
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. Raus aus dem Stapel
Die C-Sprachimplementierung lautet wie folgt:
datatype stack_pop(sqstack* s)
{
s->top--;
return s->data[s->top+1];
}
8. Holen Sie sich das oberste Element des Stapels
Die C-Sprachimplementierung lautet wie folgt:
datatype stack_top(sqstack* s)
{
return(s->data[s->top]);
}
9. Geben Sie den von malloc angeforderten Speicher frei
Die C-Sprachimplementierung lautet wie folgt:
void stack_free(sqstack *s)
{
free(s->data);
s->data=NULL;
free(s);
s=NULL;
}
Beispiel für das Drucken aller Elemente im Stapel
Die C-Sprachimplementierung lautet wie folgt:
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: Erzeugt die erforderlichen Symbolinformationen für das symbolische Debugging-Tool (GNUs GDB). Wenn wir den Quellcode debuggen möchten, müssen wir diese Option hinzufügen.
-Wall: Zeigt an, dass alle nützlichen Alarminformationen von gcc ausgegeben werden dürfen
-c: Einfach kompilieren, ohne zu verknüpfen, und die Zieldatei „.o “ generieren.
-o test: bedeutet, die Ausgabedatei in eine Datei auszugeben
Operationsergebnis:
5. Verknüpfte Listenimplementierung des Stapels
1. Definition der Datenstruktur
Bei verknüpften Listen müssen wir vor der Definition des Stapels
die folgenden Punkte berücksichtigen: 1) Die Speichermethode der Stapeldaten und der Datentyp der Stapeldaten;
2) Die Größe des Stapels;
3) Der obere Zeiger des Stapels;
Wir können eine Stapelstruktur definieren . Die C -Sprachimplementierung lautet wie folgt:
typedef int datatype;
typedef struct node{
datatype data;
struct node* next;
}listnode,*linklist;
2. Erstellen Sie einen Stapel
Die C-Sprachimplementierung lautet wie folgt:
linklist stack_create()
{
linklist s;
if((s=(linklist)malloc(sizeof(listnode)))==NULL){
puts("malloc failed");
return NULL;
}
s->next=NULL;
return s;
}
3. Räumen Sie den Stapel auf
Die C-Sprachimplementierung lautet wie folgt:
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. Stellen Sie fest, ob der Stapel leer ist
Die C-Sprachimplementierung lautet wie folgt:
int stack_empty(linklist s)
{
return (s->next==NULL ? 1:0);
}
5. In den Stapel schieben
Die C-Sprachimplementierung lautet wie folgt:
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. Herausspringen
Die C-Sprachimplementierung lautet wie folgt:
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. Holen Sie sich das oberste Element des Stapels
Die C-Sprachimplementierung lautet wie folgt:
datatype stack_top(linklist s)
{
return (s->next->data);
}
8. Geben Sie den von malloc angeforderten Speicher frei
Die C-Sprachimplementierung lautet wie folgt:
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);
}
Beispiel für das Drucken aller Elemente im Stapel
Die C-Sprachimplementierung lautet wie folgt:
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
Operationsergebnis:
6. Vor- und Nachteile zweier Implementierungen
1. Implementierung der Sequenztabelle
Wenn eine Sequenztabelle zum Implementieren eines Stapels verwendet wird, ist die konstante zeitliche Komplexität des Schiebens und Knallens des Stapels gering, und im Vergleich zur Implementierung einer verknüpften Liste kann der Vorgang zum Löschen des Stapels O (1) sein . Der einzige Nachteil besteht darin, dass er angewendet werden muss Suchen Sie im Voraus nach Platz, und wenn der Platz nicht ausreicht, ist eine Erweiterung erforderlich. Die Erweiterungsmethode wird in diesem Artikel nicht erwähnt. Sie können sich auf den Artikel „100 C/C++-Interviewbeispiele“ (4) Vektorerweiterungsstrategie beziehen .
2. Implementierung einer verknüpften Liste
Wenn Sie eine verknüpfte Liste zum Implementieren eines Stapels verwenden, ist die konstante zeitliche Komplexität des Schiebens und Knallens des Stapels etwas höher. Der Hauptgrund dafür ist, dass jedes Mal, wenn ein Stapelelement eingefügt wird, Platz beantragt werden muss und jedes Mal, wenn ein Stapelelement hinzugefügt wird Wenn es gelöscht wird, muss Speicherplatz freigegeben werden und der Vorgang zum Löschen des Stapels ist O(n). Wenn Sie den oberen Zeiger des Stapels direkt auf leer setzen, führt dies zu einem Speicherverlust. Der Vorteil besteht darin, dass kein Speicherplatz vorab zugewiesen werden muss und dass er innerhalb des zulässigen Speicherbereichs ohne Einschränkungen der Sequenztabelle auf den Stapel verschoben werden kann.