Datenstruktur – Implementierung eines sequentiellen Stapels und eines Kettenstapels

Inhaltsverzeichnis

1. Konzept

1. Definition des Stapels

2. Oberseite des Stapels

3. Unten im Stapel

2. Schnittstelle

1. Beschreibbare Schnittstelle

1) Daten werden auf den Stapel verschoben

2) Daten-Popping

3) Räumen Sie den Stapel auf

2. Schreibgeschützte Schnittstelle

1) Holen Sie sich die obersten Daten des Stapels

2) Ermitteln Sie die Anzahl der Stapelelemente

3) Stapeln Sie leere Urteile

3. Grundoperationen des Stapels

4. Implementierung des sequentiellen Stapels

1. Definition der Datenstruktur

2. Erstellen Sie einen Stapel

3. Räumen Sie den Stapel auf

4. Stellen Sie fest, ob der Stapel leer ist

5. Bestimmen Sie, ob der Stapel gesättigt ist

6. In den Stapel schieben

7. Raus aus dem Stapel

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

2. Erstellen Sie einen Stapel

3. Räumen Sie den Stapel auf

4. Stellen Sie fest, ob der Stapel leer ist

5. In den Stapel schieben

6. Herausspringen

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:
Fügen Sie hier eine Bildbeschreibung ein

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.

Supongo que te gusta

Origin blog.csdn.net/m0_74712453/article/details/135288533
Recomendado
Clasificación