栈的基本操作

1. 栈的定义

栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。如下所示:


结论:后进先出(Last In First Out),简称为LIFO线性表。

栈的基本运算有六种:

构造空栈:InitStack(SqStack &S)

判栈空:  StackEmpty(SqStack S)

判栈满: StackFull(SqStack S)

进栈: Push(SqStack &S, SElemType x)可形象地理解为压入,这时栈中会多一个元素,栈改变,所以用了&

退栈: Pop(SqStack &S, SElemType &e) 可形象地理解为弹出,弹出后栈中就无此元素了,栈改变,所以用了&

取栈顶元素:StackTop(SqStack S, SElemType &e)与弹出不同,只是使用栈顶元素的值,栈不变,所以无&。

我们要了解的是,在顺序栈中有"上溢"和"下溢"的概念。顺序栈好比一个箱子,我们在里头放了一摞砖,当我们要取砖头的话只能从第一块开始拿,那么当我们把砖头放到这个栈中超过盒子的顶部时就放不下了(超出箱子边沿高度不算),这时就是"上溢","上溢"也就是栈顶指针指出栈的外面,显然是出错了。反之,当栈中已没有砖头时,我们再去拿,看看没砖头了,把箱子拎起来看看箱底,还是没有,这就是"下溢"。"下溢"本身可以表示栈为空栈,因此可以用它来作为控制转移的条件。

下边是顺序栈的简单操作以及一个简单例子:

#include "stdafx.h"
#include <iostream>
using namespace std;

#define STACK_INIT_SIZE 10
#define STACK_INCREMENT 10
#define OVERFLOW -2
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int SElemType;
typedef int status;

typedef struct{
	SElemType *top;
	SElemType *base;
	int stacksize;
}SqStack;

status InitStack(SqStack &q)
{
	q.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof (SElemType));
	if (!q.base)
	{
		exit(OVERFLOW);
	}
	q.top = q.base;
	q.stacksize = STACK_INIT_SIZE;
	return OK;
}

status GetTop(SqStack q, SElemType &e)
{
	if (q.base == q.top)
	{
		return ERROR;
	}
	e = *(q.top - 1);
	return OK;
}

status push(SqStack &q, SElemType e)
{
	if (q.top - q.base >= q.stacksize)
	{
		q.base = (SElemType *)realloc(q.base, (q.stacksize + STACK_INCREMENT) * sizeof (SElemType));
		if (!q.base)
		{
			exit(OVERFLOW);
		}
		q.top = q.base + q.stacksize;
		q.stacksize = q.stacksize + STACK_INCREMENT;
	}
	*q.top++ = e;
	return OK;
}

status pop(SqStack &q, SElemType &e)
{
	if (q.base == q.top)
	{
		return ERROR;
	}
	e = *--q.top;
	return OK;
}
//栈的一个使用例子,数值转换,把任意一个非负十进制数转换成八进制数

status conversion()
{
	SqStack q;
	InitStack(q);
	int N;
	cout << "请输入十进制数:" << endl;
	cin >> N;
	while (N)
	{
		push(q, N%8);
		N = N/8;
	}
	int e;
	cout << "输出八进制数:" << endl;
	while (q.base != q.top)
	{
		pop(q, e);
		cout << e;
	}
	return OK;
}
int _tmain(int argc, _TCHAR* argv[])
{
	SqStack s;
	InitStack(s);
	for (int i = 0; i < 10; i++)
	{
		push(s, i);
	}
	SElemType e;
	GetTop(s, e);
	cout << "当前栈大小为:" << s.stacksize << endl;
	cout << "栈顶元素为" << e << endl;
	push(s, 10);
	pop(s, e);
	cout << "栈大小变为:" << s.stacksize << endl;
	cout << "栈顶元素为" << e << endl;
	conversion();
	system("pause");
	return 0;
}

realloc原型是extern void *realloc(void *mem_address, unsigned int newsize);

功能:

先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值