データ構造-スタック(C言語)

githubコードのダウンロード

githubコード:https
//github.com/Kyrie-leon/Data_Structures/tree/main/stack_queue

1.スタックの概念と構造

スタック要素の挿入および削除操作のために一方の端のみが固定されている特別な線形形式データの挿入および削除操作の一方の端はスタックの最上位と呼ばれ、もう一方の端はスタックの最下部と呼ばれます。スタック内のデータ要素は従いますLIFO(後入れ先出し)原則として。
プッシュ:スタックを挿入する操作は、プッシュ/プッシュ/プッシュと呼ばれます。着信データはスタックの一番上にあります
ポップ:スタックの削除操作はポップと呼ばれます。データもスタックの一番上にあります
ここに画像の説明を挿入します
ここに画像の説明を挿入します

第二に、スタックの実装

スタックの実装は、通常、配列またはリンクリストを使用し実装でき、配列の構造は比較的優れています。配列が入っているのでテールにデータを挿入するコストは比較的小さい、以下に示すように。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

ただし、次の構造を使用してスタックを実装する場合、テール挿入でデータを移動する必要があり、多くの計算オーバーヘッドが発生します。

ここに画像の説明を挿入します

2.1スタックストレージの定義

静的ストレージスタックは
、静的な1次元配列a [N]を使用して実装されますが、そうすると、スペースの浪費が多すぎたり、スペースが不足したりします。

#define N 10
typedef int STDataType;
typedef struct Stack Stack;
struct Stack
{
    
    
	STDataType a[N];
	int _top;	//栈顶
};

スタックの動的な
拡張をサポートします。ポインタ_aを使用してメモリを動的に開き、スタックストレージを実現します。

typedef int STDataType;
typedef struct Stack Stack;
//支持动态增长的栈
struct Stack
{
    
    
	STDataType * _a;
	int _top;			//栈顶
	int _capacity;		//容量
};

2.2スタックの初期化

初期化:デフォルトでは、4つのSTDataTypeサイズのスペースがスタック用に開かれます

  • 容量:スタックの容量、デフォルトは4
  • _top:スタック最上位を示します。_top= 0はスタックが空であることを意味することに同意します。その後、_topはスタックにプッシュされる要素ごとに1ずつ増加します。つまり、_topが指す配列の次のテーブルは、実際のスタックトップ要素の添え字よりも常に1大きくなります。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

//栈的初始化
void StackInit(Stack * ps)
{
    
    
	assert(ps);
	ps->_a = (STDataType *)malloc(sizeof(Stack) * 4);	//默认数组大小为4
	ps->_top = 0;		//栈为空,则栈顶为0
	ps->_capacity = 4;	//默认栈的容量为4
}

2.3スタックにプッシュします

_topが指す配列の次のテーブルは、実際のスタックトップ要素インデックスよりも常に1大きいこと合意されています。
データを_topインデックスの配列に格納してから、_topに1を追加するだけで済みます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

//入栈
void StackPush(Stack * ps, STDataType data)
{
    
    
	assert(ps);
	//判断栈是否满了,满了则增容
	if (ps->_top == ps->_capacity)
	{
    
    
		ps->_capacity *= 2;	//每次扩容2倍
		STDataType * tmp = (STDataType *)realloc(ps->_a, sizeof(Stack)*ps->_capacity);
		//判断内存是否申请成功
		if (NULL == tmp)
		{
    
    
			printf("扩容失败\n");
			exit(-1);
		}
		ps->_a = tmp;
	}
	//入栈
	ps->_a[ps->_top] = data;	
	ps->_top++;
}

2.4ポップ

_topが指す配列の次のテーブルは、実際のスタックトップ要素の添え字よりも常に1大きくなります。
したがって、_topを1だけ減らす必要があります。

ここに画像の説明を挿入します

//出栈
void StackPop(Stack * ps)
{
    
    
	assert(ps);
	assert(ps->_top>0);
	ps->_top--;
}

2.5スタックの最上位要素を取得します

_topが指す配列の次のテーブルは、実際のスタックトップ要素の添え字よりも常に1大きくなります。
したがって、スタックの最上位要素の添え字は_top-1です。

//获取栈顶元素
STDataType StackTop(Stack *ps)
{
    
    
	assert(ps);
	assert(ps->_top>0);

	return ps->_a[ps->_top-1];	
}

2.6スタック内の有効な要素の数を取得する

配列要素のインデックスは0から始まるため、_topはスタック内の有効な要素の数を表します


//获取栈中有效元素个数
int StackSize(Stack * ps)
{
    
    
	assert(ps);
	return ps->_top;
}

2.7スタックが空かどうかを確認します

_topの値を使用して、スタックが空かどうかを判断できます
。_topが0の場合は空であることを意味します
。_topが1の場合は空ではないことを意味します。_topが1の場合は空ではないことを意味します。負の場合は0を返します。

//检测栈是否为空,如果为空返回非0,不为空返回0
int StackEmpty(Stack* ps)
{
    
    
	assert(ps);
	return !(ps->_top);
}

2.8スタックを破壊する


//销毁栈
void StackDestory(Stack * ps)
{
    
    
	assert(ps);
	free(ps->_a);
	ps->_a = NULL;
	ps->_capacity = ps->_top = 0;
}

3、スタックテスト

#include "stack.h"

void TestStack()
{
    
    
	Stack ps;
	StackInit(&ps);
	StackPush(&ps, 1);
	StackPush(&ps, 2);
	StackPush(&ps, 3);
	StackPush(&ps, 4);
	StackPush(&ps, 5);
	while (!StackEmpty(&ps))
	{
    
    

		printf("%d, %d\n", StackTop(&ps),StackSize(&ps));
		StackPop(&ps);
	}

	
}

int main()
{
    
    
	TestStack();
	system("pause");
	return 0;
}

ここに画像の説明を挿入します

第四に、コードリスト

4.1 stack.h

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

#define N 10
typedef int STDataType;
typedef struct Stack Stack;
//struct Stack
//{
    
    
//	STDataType a[N];
//	int _top;	//栈顶
//};

//支持动态增长的栈
struct Stack
{
    
    
	STDataType * _a;
	int _top;			//栈顶
	int _capacity;		//容量
};

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

//入栈
void StackPush(Stack * ps, STDataType data);

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

//获取栈顶元素
STDataType StackTop(Stack *ps);

//获取栈顶中有效元素个数
int StackSize(Stack * ps);

//检测栈是否为空,如果为空返回非0,不为空返回0
int StackEmpty(Stack* ps);

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

4.2 stack.c

#include "stack.h"

//栈的初始化
void StackInit(Stack * ps)
{
    
    
	assert(ps);
	ps->_a = (STDataType *)malloc(sizeof(Stack) * 4);	//默认数组大小为4
	ps->_top = 0;		//栈为空,则栈顶为0
	ps->_capacity = 4;	//默认栈的容量为4
}

//入栈
void StackPush(Stack * ps, STDataType data)
{
    
    
	assert(ps);
	//判断栈是否满了,满了则增容
	if (ps->_top == ps->_capacity)
	{
    
    
		ps->_capacity *= 2;	//每次扩容2倍
		STDataType * tmp = (STDataType *)realloc(ps->_a, sizeof(Stack)*ps->_capacity);
		//判断内存是否申请成功
		if (NULL == tmp)
		{
    
    
			printf("扩容失败\n");
			exit(-1);
		}
		ps->_a = tmp;
	}
	//入栈
	ps->_a[ps->_top] = data;	
	ps->_top++;
}

//出栈
void StackPop(Stack * ps)
{
    
    
	assert(ps);
	assert(ps->_top>0);
	ps->_top--;
}

//获取栈顶元素
STDataType StackTop(Stack *ps)
{
    
    
	assert(ps);
	assert(ps->_top>0);

	return ps->_a[ps->_top-1];	
}

//获取栈中有效元素个数
int StackSize(Stack * ps)
{
    
    
	assert(ps);
	return ps->_top;
}

//检测栈是否为空,如果为空返回非0,不为空返回0
int StackEmpty(Stack* ps)
{
    
    
	assert(ps);
	return !(ps->_top);
}

//销毁栈
void StackDestory(Stack * ps)
{
    
    
	assert(ps);
	free(ps->_a);
	ps->_a = NULL;
	ps->_capacity = ps->_top = 0;
}

4.3 test.c

#include "stack.h"

void TestStack()
{
    
    
	Stack ps;
	StackInit(&ps);
	StackPush(&ps, 1);
	StackPush(&ps, 2);
	StackPush(&ps, 3);
	StackPush(&ps, 4);
	StackPush(&ps, 5);
	while (!StackEmpty(&ps))
	{
    
    

		printf("%d, %d\n", StackTop(&ps),StackSize(&ps));
		StackPop(&ps);
	}

	
}

int main()
{
    
    
	TestStack();
	system("pause");
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_40076022/article/details/112282137