栈的基本操作
2015-11-26 21:26
155 查看
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),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
相关文章推荐
- 第一个项目:五子棋
- 史上最好看的电影你看过吗
- php正则表达式速查手册
- Delphi使用XmlHttp获取时间
- Beta版本冲刺计划
- android应用添加欢迎界面
- 数据结构——单向传统链表(java实现)
- 驱动-Hello,World
- 如何在VMware Workstation搭建vCAC 6.2实验环境 - 第二部分
- ubuntu安装lamp&&mysql中修改配置文件显示中文&&强大的vim配置&&c++连接Mysql
- 关于/dev/shm的文章
- LeetCode---Count and Say
- 字符串匹配算法总结
- 用JAVA写的一个只基于awt的计算器---比较简陋,继续加油!
- spring bean单例模式改成原型模式
- 提升进程权限为DEBUG权限
- 继承,初始化方法,便利构造器
- HTML常见的实体字符
- 【云快讯】HP 将关闭公有云服务,转售微软的 Azure 云服务
- Android Studio 导入github源码