数据结构:顺序栈的实现

1、快速开始

  栈是一种遵循元素后进(Push)先出(Pop)规则的线性表,即最后加入的元素最先出来,它的实现可以用数组或者链表。

  

  

  它的特点如下:

  • 后入先出,先入后出。
  • 除了头尾节点之外,每一个元素有一个前驱,有一个后继。  

2、实现栈

  我们已经说过了,栈是一种线性表,故其底层是基于数组或者链表的。那么,我们的重点是维护一种规则,即后进先出。

  我们始终要有一个变量L来记录最后一个元素的位置:

  • 当压入时,将新元素插入到L位置之后,然后更新L,即L+1.

  • 当弹出时,将L位置元素进行删除,然后更新L,即L-1。

  也正是因为,我们使用的是线性表,正好可以利用其尺寸来表示L,即线性表的大小可以表示最后一个元素的位置。

2.1、栈的实现

class MyStack {
private List<Integer> data; // 存储元素
public MyStack() {
data = new ArrayList<>();
}
/**插入一个元素到栈中. */
public void push(int x) {
data.add(x);
}
/**检查是否为空 */
public boolean isEmpty() {
return data.isEmpty();
}
/**到达栈顶. */
public int top() {
return data.get(data.size() - 1);
}
/** 删除一个元素. 操作成功返回true. */
public boolean pop() {
if (isEmpty()) {
return false;
}
data.remove(data.size() - 1);
return true;
}
};

  

3、C语言版本实现

3.1、对栈的结构定义:

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

说明:

    1.base表示栈底指针,在判断出栈、初始化和重新分配空间的时候需要用到。

    2.top表示栈顶指针,是栈最关键和核心的组成,入栈时top向上移动,出栈时top向下移动。

    3.此处的stacksize并不表示当前的栈中的元素数量,而是表示栈的容量,也就是能装多少个元素。

3.2、初始化栈:

int initStack(SqSatck *S)
{
S->base=(int*)malloc(100*sizeof(int));
if(!S)
return 0; //0代表操作失败
S->top=S->base;
stacksize=100;
return 1; //1代表操作完成
}

说明:

    1.顺序栈初始化无非就是给栈分配连续的内存空间,base是栈底指针,在上面提到过,它用来指示一段连续的内存空间的首地址,也就是用来初始化。

    2.分配空间不意味着一定会有那么多空间,所以判断也不可缺少。

    3.分配空间后,base和top的地址应该一致,此时top还没有移动。

3.3、压栈

int push(SqStack * S,int elem)
{
if(S->top-S->base>=S->stacksize)
{
S->base=(SElemType *)
realloc(S->base,(S->stacksize+10)*sizeof(SElemType)); //10代表增量,你可以使用宏定义,方便后续修改。
if(!S->base)
return 0;
S->top=S->base+S->stacksize;
S->stacksize+=10
}
*S->top++=elem;
return 1;
}

  说明:

    1.压栈是栈的核心操作,关键步骤无非是*S->top++=elem;但是在进行此步操作时,一定要判断栈是否超出容量。

    2.如果栈超出容量,则要在进行原空间的基础上重新分配空间,realloc是关键的命令。

  realloc 
    原型:extern void *realloc(void *mem_address, unsigned int newsize); 
    用法:#include <stdlib.h> 有些编译器需要#include <alloc.h> 
    功能:改变mem_address所指内存区域的大小为newsize长度。 
    说明:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 
    当内存不再使用时,应使用free()函数将内存块释放。

    3.分配空间以后,在修改stacksize之前,top应该保持在容量顶端,S->top=S->base+S->stacksize;

2.4出栈

int pop(SqStack *q)
{
if(S->top==S->base)
return 0;
return *S->--top;;
}

说明:

    1.出栈是简单操作,其实这里并没有完美的实现这个效果,你应该考虑到如果在扩容后又迅速减小,会造成大量的空间浪费。

2.5遍历栈

int printfStack(SqStack *S)
{
int *p=S->base;
puts("输出栈");
for(p;p!=S->top;p++)
{
printf("***%d",*p);
}
}

  

数据结构:C_顺序栈的实现的更多相关文章

  1. 数据结构之顺序栈SqStack

    顺序栈SqStack 基本操作 Status InitStack()//构造一个空栈S Status DestroyStack()//销毁栈S,S不再存在 Status ClearStack()//把 ...

  2. 数据结构Java实现05----栈:顺序栈和链式堆栈

    一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  3. 数据结构Java实现03----栈:顺序栈和链式堆栈

    一.堆栈的基本概念: 堆栈(也简称作栈)是一种特殊的线性表,堆栈的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置进行插入和删除操作,而堆栈只允许在固定一端进行插入和删除 ...

  4. 利用顺序栈解决括号匹配问题(c++)-- 数据结构

    题目: 7-1 括号匹配 (30 分)   给定一串字符,不超过100个字符,可能包括括号.数字.字母.标点符号.空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配. 输入格式: 输入在一行 ...

  5. 顺序栈操作--数据结构(C++)版

    最近学习数据结构,一开始接触感觉好难,颓废了一段时间,后来又重新翻开学习,突然感觉到很大的兴趣.对这些代码的运用都有了 一些新的认识.下面简单的讲述下最新学到的顺序栈,不知道大家学习的时候会不会有感觉 ...

  6. 【C#】【数据结构】005-栈:顺序栈

    C#数据结构:顺序栈 1.自定义顺序栈结构: /// <summary> /// 顺序栈 /// </summary> /// <typeparam name=" ...

  7. 数据结构 - 顺序栈的实行(C语言)

    数据结构-顺序栈的实现 1 顺序栈的定义 既然栈是线性表的特例,那么栈的顺序存储其实也是线性表顺序存储的简化,我们简称为顺序栈.线性表是用数组来实现的,对于栈这种只能一头插入删除的线性表来说,用数组哪 ...

  8. [Python] 数据结构--实现顺序表、链表、栈和队列

    说明: 本文主要展示Python实现的几种常用数据结构:顺序表.链表.栈和队列. 附有实现代码. 来源主要参考网络文章. 一.顺序表 1.顺序表的结构 一个顺序表的完整信息包括两部分,一部分是表中元素 ...

  9. [C++]数据结构:栈之顺序栈

    0 栈的基本概念 栈,根据存储结构的不同,可分为:链栈和顺序栈. 1 顺序栈的知识概览 2 编程复现 2.1 定义基本数据结构 typedef char DataType; // 基本数据类型 enu ...

随机推荐

  1. Shiro权限验证代码记录,正确找到shiro框架在什么地方做了权限识别

    权限验证方式的验证代码: org.apache.shiro.web.servlet.AdviceFilter这个类是所有shiro框架提供的默认权限验证实例类的父类 验证代码: public void ...

  2. 用Win7自带的磁盘管理工具给硬盘分区

    最近新买了一台笔记本,要给硬盘分几个区,心想还是用个工具方便点,于是就上网准备下个“硬盘分区魔术师”,但是看到有一篇文章介绍Win7系统也自带了硬盘分区工具,这我以前倒没听说过,试了一下,还挺方便好用 ...

  3. wireshark常用过滤规则

    wireshark常用过滤规则:(Filter中输入过滤规则)1.源ip过滤:ip.src==1.1.1.1               (过滤源ip为1.1.1.1的包) 2.目的ip过滤:ip.d ...

  4. 《理解 ES6》阅读整理:函数(Functions)(六)Purpose of Functions

    明确函数的双重作用(Clarifying the Dual Purpose of Functions) 在ES5及更早的ES版本中,函数调用时是否使用new会有不同的作用.当使用new时,函数内的th ...

  5. java 内存机制

    1.Java的内存机制 Java 把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在 ...

  6. anyncTask的3个参数

    AnyncTask异步处理数据并将数据应用到视图的操作场合 一  其中包含这几个方法 1 onPreExcute() 初始化控件,例如进度条2 doInBackground() 具体的执行动作请求数据 ...

  7. 老猪带你玩转android自定义控件一——打造最简单viewpagerindicator

    viewpagerindicator,既使用viewpager翻页时候,标题的指示条随着改变的控件,是常用android控件之一,几乎所有的新闻类APP中都有使用.如下图所示: 今天,我们将从0到1实 ...

  8. ASP.NET 4.5.256 has not been registered on the Web server. You need to manually configure your Web server for ASP.NET 4.5.256 in order for your site to run correctly

    Microsoft .NET Framework 4.6安装后,用户可能会在使用Microsoft Visual Studio 创建(或打开现有项目时)网站.或Windows Azure项目时遇到下面 ...

  9. 分享一个漂亮的ASP.NET MVC界面框架

    本文分享一个插件化的界面框架,该框架提供了用户.角色.权限管理功能,也提供了插件的管理和插件中心.下图是该界面框架的样式(全部源码和原理介绍下一篇分享,推荐越多,源码放的越早,呵呵). 要使用该界面框 ...

  10. Nodejs·网络服务

    本章是从NodeJS拥有的模块角度,讲述了网络服务中的应用: net ----- > TCP dgram --> UDP http -----> HTTP https ----> ...