数据结构初阶 --- 栈(数组栈)

目录

一.栈的概念和结构

 二.栈的各个函数接口及实现

1.动态数组栈的结构体定义

2.栈的初始化

3.栈的销毁

4.在栈顶插入数据(入栈)

5.删除栈顶数据(出栈)

6.取出栈顶的数据

7.栈内的元素个数

8.判断栈的是否为空

三.关于栈的选择题

一.栈的概念和结构

栈:是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端 称为栈顶,另一端为栈底。栈中的数据元素遵守 后进先出 LIFO (Last In First Out)的原则。

栈可以用数组来实现,也可以用链表来实现,相对而言数组栈会更优一点。(数组栈在尾上删除数据会更容易一点,代价小)

数组实现栈:

如果用链表来实现栈,如果让链表的头作栈顶,就是头插头删。(可以设计成单向链表)

                                    如果让链表的尾做栈顶,就是尾插尾删。(最好设计成双向链表)

 二.栈的各个函数接口及实现

1.动态数组栈的结构体定义

a是指向数组的指针;top表示栈顶;capacity表示数组的实际容量。

(我们这里实现的是一个动态的数组栈,空间不够时,可以动态增容)

typedef int STDataType;

typedef struct Stack
{
	STDataType* a;
	int top;//栈顶
	int capacity;//容量
}ST;

2.栈的初始化

初始化:这里把top初始化成 0 ,则top就代表栈顶的下一个数据的下标位置。

                                                     (这个时候的top也代表了栈内数据的个数)

              如果这里把top初始化成 -1 ,则top就代表栈顶数据的下标位置。

void StackInit(ST* ps)//初始化栈
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

3.栈的销毁

释放a指针所指向的连续的空间,把a指针置空,把top和capacity置0.

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

4.在栈顶插入数据(入栈)

压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶
对于数组进行插入操作时,需要注意的是:要首先检查数组空间够不够,不够了就要进行扩容操作;空间够的话,就可以进行插入操作了。
void StackPush(ST* ps, STDataType x)//增加,入栈
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType)*newcapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

5.删除栈顶数据(出栈)

出栈:栈的删除操作叫做出栈。 出数据也在栈顶
对于删除操作,需要注意的是:
如果栈已经为空(top==0)的时候,就不能进行删除操作了。
如果栈不为空(top!=0)时,让top--,就完成了数组栈的删除操作了。
bool StackEmpty(ST* ps)//判断栈是否为空
{
	assert(ps);
	return ps->top == 0;



	/*if (ps->top == 0)
		return true;
	else
		return false;*/

}

void StackPop(ST* ps)//删除,出栈
{
	assert(ps);
	assert(!StackEmpty(ps));//判断栈是否为空
	ps->top--;
}

6.取出栈顶的数据

首先栈不为空时,才有栈顶数据,所以要先判断栈是否为空。

栈不为空时,取出栈顶数据( ps->a[ps->top-1] )就可以了。

bool StackEmpty(ST* ps)//判断栈是否为空
{
	assert(ps);
	return ps->top == 0;



	/*if (ps->top == 0)
		return true;
	else
		return false;*/

}

STDataType StackTop(ST* ps)//栈顶的数据,获取栈顶数据
{
	assert(ps);
	assert(!StackEmpty(ps));//判断栈是否为空
	return ps->a[ps->top-1];
}

7.栈内的元素个数

top的值就是栈内的元素个数了。

int StackSize(ST* ps)//栈内数据的多少,获取栈中有效元素的个数
{
	assert(ps);
	return ps->top;
}

8.判断栈的是否为空

判断栈是否为空:如果top==0,则栈为空;  如果top!=0, 则栈不为空。

bool StackEmpty(ST* ps)//判断栈是否为空
{
	assert(ps);
	return ps->top == 0;



	/*if (ps->top == 0)
		return true;
	else
		return false;*/

}

三.关于栈的选择题

选择题1:

1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是( 
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1

选择题2:

2. 一个栈的初始状态为空。现将元素 1 2 3 4 5 A B C D E 依次入栈,然后再依次出栈,则元素出
栈的顺序是(  B  )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA
解:题目中说是依次入栈,就是都入栈以后才开始依次出栈,所以就是很常规的那种,栈遵         循后进先出的规则。    所以出栈顺序就是入栈顺序的逆序。
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值