【数据结构】栈和队列

概念

栈是一种特殊的线性表,数据进出栈遵循“后进先出”的原则(last in first out)。

压栈:是指数据从栈顶进入

出栈:是指数据从栈顶出去

 

栈的实现思路

可以用顺序表和链表两种形式

1)用顺序表

可以考虑用动态和静态两种,一般会选择动态,可以进行扩容处理,有利于高效利用空间

709075a9544d49fd81f1a05d3abeebd3.jpg

2)用链表

这时候就要考虑链表的形式以及栈顶位置的选取(会影响时间复杂度),如果用单链表,若栈顶选择链表尾,保存尾指针,入栈可以采取尾插形式,出栈就必须先找到尾指针的前一个,需要遍历链表,时间复杂度较高;若栈顶选择头指针,入栈可以采取头插,出栈可以采取尾插,时间复杂度和空间复杂度都比较高。如果用双向链表,也可以实现栈的相应功能,但是并不是最优的。

e1914fa9cd97450ab6129c9e86643b34.jpg

栈的代码实现

先创建一个新的工程Stack,创建头文件Stack.h(放函数声明),源文件Stack.c(放函数定义),test.c(测试文件)

先在Stack.h中写上与栈有关的结构体,用动态顺序表来实现

typedef int STDataType;
#define m 3
typedef struct Stack
{
	STDataType* a;//动态数组->存放数据
	STDataType pop;//栈顶
	int capacity;//数组容量大小
}ST;

【1】初始化函数STInit

void STInit(ST* p)
{
	STDataType* q= (STDataType*)malloc(sizeof(STDataType)*m);
	if (q == NULL)
	{
		perror("malloc fail!");
		return;
	}
	p->a = q;
	p->pop = 0;//指向栈顶元素的下一个元素
	p->capacity = m;
}

【2】销毁函数STDestroy

void STDestroy(ST* p)
{
	assert(p);
	free(p->a);
	p->a = NULL;
}

【3】入栈函数STPush

void STPush(ST* p, STDataType x)
{
	assert(p);
	if (p->pop == p->capacity)
	{
		STDataType* q = (STDataType*)realloc(p->a, sizeof(STDataType)* p->capacity * 2);
		if (q == NULL)
		{
			perror("mallo fail!");
			return;
		}
		else
		{
			p->a = q;
			p->capacity *= 2;
		}
	}
	p->a[p->pop] = x;
	p->pop++;
}

【4】出栈函数STPop

void STPop(ST* p)
{
	assert(p);
	assert(!STempety(p));//非空为真,那么STempty为假
		p->pop--;
}

【5】找栈顶元素函数STTop

STDataType STTop(ST* p)
{
	assert(p);
	return p->a[p->pop - 1];
}

【6】判断是否为空函数STempety

bool STempety(ST* p)
{
	return p->pop == 0 ? 1 : 0;//pop==0表示没有元素
}

【7】查询栈中元素个数函数STSize

int STSize(ST* p)
{
	assert(p);
	return p->pop - 1;
}

代码完整表示:

Stack.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include<assert.h>

typedef int STDataType;
#define m 3
typedef struct Stack
{
	STDataType* a;//动态数组->存放数据
	STDataType pop;//栈顶
	int capacity;//数组容量大小
}ST;

void STInit(ST* p);
void STDestroy(ST* p);
void STPush(ST* p, STDataType x);
void STPop(ST* p);//也可以考虑将STop与STTop合并写成一个函数
STDataType STTop(ST* p);
bool STempety(ST* p);
int STSize(ST* p);

Stack.c

#include"Stack.h"

void STInit(ST* p)
{
	STDataType* q= (STDataType*)malloc(sizeof(STDataType)*m);
	if (q == NULL)
	{
		perror("malloc fail!");
		return;
	}
	p->a = q;
	p->pop = 0;//指向栈顶元素的下一个元素
	p->capacity = m;
}
void STDestroy(ST* p)
{
	assert(p);
	free(p->a);
	p->a = NULL;
}
void STPush(ST* p, STDataType x)
{
	assert(p);
	if (p->pop == p->capacity)
	{
		STDataType* q = (STDataType*)realloc(p->a, sizeof(STDataType)* p->capacity * 2);
		if (q == NULL)
		{
			perror("mallo fail!");
			return;
		}
		else
		{
			p->a = q;
			p->capacity *= 2;
		}
	}
	p->a[p->pop] = x;
	p->pop++;
}
void STPop(ST* p)
{
	assert(p);
	assert(!STempety(p));//非空为真,那么STempty为假
		p->pop--;
}
STDataType STTop(ST* p)
{
	assert(p);
	return p->a[p->pop - 1];
}
bool STempety(ST* p)
{
	return p->pop == 0 ? 1 : 0;//pop==0表示没有元素
}
int STSize(ST* p)
{
	assert(p);
	return p->pop - 1;
}

test.c

#include"Stack.h"

void test1()
{
	ST p;
	STInit(&p);
	STPush(&p, 1);
	STPop(&p);
	printf("1 ");
	STPush(&p, 2);
	STPush(&p, 3);
	STPop(&p);
	printf("3 ");
	STPush(&p, 4);
	STPush(&p, 5);
	STPush(&p, 6);
	while (!STempety(&p))
	{
		printf("%d ",STTop(&p));
		STPop(&p);
	}
}
int main()
{
	test1();
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伱恏呀呀呀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值