<Datenstruktur> Implementierung des Stapels

Inhalt

Vorwort

       Stack-Konzept

       Stapelstruktur

Implementierung von Stack

       Stapelstruktur erstellen

       Stack initialisieren

       Stapel zerstören

       auf den Stapel schieben

       Pop

       Holen Sie sich das oberste Element des Stapels

       Holen Sie sich die Anzahl gültiger Elemente im Stack

       Überprüfen Sie, ob der Stapel leer ist

Gesamtcode

       Stack.h-Datei

       Stack.c-Datei

       Test.c-Datei


Vorwort

Stack-Konzept

  • Stack: Eine spezielle lineare Liste, die das Einfügen und Entfernen von Elementen nur an einem festen Ende erlaubt. Ein Ende, an dem Daten eingefügt und gelöscht werden, wird als oberes Ende des Stapels bezeichnet, und das andere Ende wird als unteres Ende des Stapels bezeichnet. Die Datenelemente im Stack folgen dem LIFO-Prinzip (Last In First Out). Ähnlich wie bei einem Pistolenmagazin wird immer zuerst die zuletzt geladene Kugel abgefeuert, es sei denn, die Waffe ist kaputt.
  • Stack schieben: Der Vorgang des Einfügens des Stacks wird Push/Push/Push genannt. (Eingehende Daten stehen ganz oben im Stack)
  • Pop: Das Löschen des Stacks wird als Pop bezeichnet. (Die Ausgabedaten befinden sich ebenfalls oben auf dem Stapel)

Notiz:

1. Funktionsaufrufe haben auch Stacks Gibt es einen Unterschied zwischen diesen beiden Stacks?

Natürlich gibt es Unterschiede. Der Funktionsaufruf ruft den Stapelrahmen auf, und es gibt auch einen Stapelspeicher im Speicher. Wenn das Programm ausgeführt wird, muss die Funktion ausgeführt werden. Die lokalen Variablen, Parameter, Rückgabewerte usw. in der Funktion müssen in gespeichert werden Funktionsstapelrahmen.

Die beiden Stacks haben nichts miteinander zu tun, einer ist der Stack in der Datenstruktur. Der andere ist ein im Betriebssystem unterteilter Speicherbereich, der als Stapel bezeichnet wird und zum Erstellen eines Stapelrahmens verwendet wird, wenn eine Funktion aufgerufen wird. Obwohl es in der Natur keine Verbindung gibt, entsprechen sie alle der Last-in-First-out-Regel.

2. Angenommen, die Stapelfolge lautet: 1 2 3 4, dann muss die Popout-Reihenfolge lauten: 4 3 2 1?

natürlich nicht. Obwohl die Regeln eindeutig LIFO sind, ist dies relativ gesagt.Wenn gesagt wird, dass es jedes Mal, wenn es in eines eindringt und dann eines losgelassen wird, und dann den Stapel weiter schiebt, entspricht es nicht auch dem Last-in-First- Regel? Genau wie im obigen Beispiel ist es nicht verwunderlich, dass Sie sagen, dass die Stapelreihenfolge 1 2 3 4 ist. Jedes Mal, wenn Sie eins eingeben, geht eines hinaus und eines hinein, was ebenfalls den Regeln entspricht. Es ist auch möglich, zwei in den Stapel zu schieben und dann wieder rein und raus zu gehen, z. B. 2 1 4 3.

Stapelstruktur

Implementierung von Stack

Stapelstruktur erstellen

  • Stack.h-Datei:
//创建栈结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* a; //存储数据
	int top; //栈顶的位置
	int capacity; //容量
}ST;

Stack initialisieren

  • Gedanke:

Die Initialisierung ist relativ einfach.Nach dem Erlernen der vorherigen Sequenztabelle ist es sehr einfach, den Stack zu initialisieren

  • Stack.h-Datei:
//初始化栈
void StackInit(ST* ps);
  • Stack.c-Datei:
//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}
  • Notiz:

​​​Es ist beabsichtigt, top auf 0 zu setzen, wenn Sie hier initialisieren. Zuallererst wurde es markiert, als die Stapelstruktur oben erstellt wurde. top wird verwendet, um die Position der Oberseite des Stapels aufzuzeichnen. Da es sich um die Position der Oberseite des Stapels handelt, wenn top auf 0 initialisiert wird, we kann die Daten direkt in den Stack legen und dann top++ , aber wenn top auf -1 initialisiert wird, muss top ++ an die erste Stelle setzen, da Daten nicht an einer Position abgelegt werden können, an der eine negative Zahl nicht zum Stack gehört. Die folgende Abbildung veranschaulicht den Vorgang:

 Dieser Artikel verwendet top = 0 als Beispiel

Stapel zerstören

  • Gedanke:

Der dynamisch geöffnete Speicherplatz muss freigegeben werden, free kann auf leer gesetzt werden, die restlichen Daten werden auf 0 gesetzt.

  • Stack.h-Datei:
//销毁栈
void StackDestory(ST* ps);
  • Stack.c-Datei:
//销毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

auf den Stapel schieben

  • Ideen:

Der vorherige Artikel hat betont, dass top mit 0 initialisiert wird, also direkt in die Daten geschoben werden sollte, und top++, aber vorher muss beurteilt werden, ob der Speicherplatz ausreicht.Wenn top=capacity, ist der Stack voll, dann muss realloc erweitert werden.

  • Stack.h-Datei:
//压栈
void StackPush(ST* ps, STDataType x);
  • Stack.c-Datei:
//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//如果栈满了,考虑扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量
		ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newcapacity; //更新容量
	}
	ps->a[ps->top] = x;//将数据压进去
	ps->top++;//栈顶上移
}

Pop

  • Ideen:

Bevor Sie den Stack platzen lassen, vergewissern Sie sich, dass top nicht leer ist und die Bedingung dafür, dass top nicht leer ist, top>0 ist, also müssen Sie auch behaupten, dass top>0, und dann direkt die Spitze des Stacks nach unten verschieben -- das ist es. Ähnlich der Idee einer Sequenztabelle.

  • Stack.h-Datei:
//出栈
void StackPop(ST* ps);
  • Stack.c-Datei:
//出栈
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

Holen Sie sich das oberste Element des Stapels

  • Ideen:

Zuerst müssen wir herausfinden, wer das oberste Element des Stapels ist, ist es die oberste Position oder die Top-1-Position? Offensichtlich ist die Top-1-Position das oberste Element des Stacks, da während der obigen Initialisierung klar darauf hingewiesen wurde, dass Top 0 war, und die Daten direkt in den Stack gelegt wurden, als er verschoben wurde. Zu diesem Zeitpunkt das erste data index 0 ist, und dann + +top und dann andere Daten pushen, ist ersichtlich, dass das oberste Element des Stapels die Position des Index top-1 ist.

  • Stack.h-Datei:
//访问栈顶数据
STDataType StackTop(ST* ps);
  • Stack.c-Datei:
//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素
}

Holen Sie sich die Anzahl gültiger Elemente im Stack

  • Gedanke:

Wie oben erwähnt, ist der Index top-1 das oberste Element des Stapels, bedeutet dies also, dass es insgesamt Top-1-Elemente gibt? Natürlich nicht, hier ist die gleiche Idee wie beim Array-Index, die Anzahl der Elemente sollte oben sein, geben Sie es einfach direkt zurück.

  • Stack.h-Datei:
//有效元素个数
int StackSize(ST* ps);
  • Stack.c-Datei:
//有效元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

Überprüfen Sie, ob der Stapel leer ist

  • Ideen:

Wenn der Wert von top 0 ist, ist es leer und return kann direkt zurückgegeben werden.

  • Stack.h-Datei:
//判空
bool StackEmpty(ST* ps);
  • Stack.c-Datei:
//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0; //如果top为0,那么就为真,即返回
}
  • Test.c-Datei:
void TestStack()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	StackDestory(&st);
}
  • Die Wirkung ist wie folgt:

Gesamtcode

Stack.h-Datei

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

//创建栈结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* a; //存储数据
	int top; //栈顶的位置
	int capacity; //容量
}ST;

//初始化栈
void StackInit(ST* ps);

//销毁栈
void StackDestory(ST* ps);

//压栈
void StackPush(ST* ps, STDataType x);

//出栈
void StackPop(ST* ps);

//判空
bool StackEmpty(ST* ps);

//访问栈顶数据
STDataType StackTop(ST* ps);

//有效元素个数
int StackSize(ST* ps);

Stack.c-Datei

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

//销毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//如果栈满了,考虑扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量
		ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newcapacity; //更新容量
	}
	ps->a[ps->top] = x;//将数据压进去
	ps->top++;//栈顶上移
}
//出栈
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0; //如果top为0,那么就为真,即返回
}

//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素
}

//有效元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

Test.c-Datei

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void TestStack()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	StackDestory(&st);
}
int main()
{
	TestStack();
	return 0;
}

Ich denke du magst

Origin blog.csdn.net/bit_zyx/article/details/123763458
Empfohlen
Rangfolge