数据结构入门(四)-栈的定义与实现
来源:互联网 发布:c语言编程软件手机版 编辑:程序博客网 时间:2024/05/18 20:49
1.栈的定义
栈
(stack)是限定仅在标尾进行插入和删除操作的线性表。
我们把允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何数据元素的栈称为空栈。栈又称为后进后出
(Last In First Out)的线性表简称==LIFO==结构
很多软件比如 Word,Photoshop等文档或图像编辑软件中都有撤销(undo)的操作,也就是用栈的方式来实现的。
栈
的插入操作,叫做进栈,也称压栈,入栈。 栈
的删除操作,叫做出栈,也有的叫做弹栈。
进栈出栈的变化形式
- 1,2,3 进 =》 3,2,1出
- 1进,1出;2进,2出,3进,3出
- 1进,2进,2出,1出,3进,3出
- 1进,1出,2进,3进,3出,2出
- 1进,2进,2出,3进,3出,1出
栈的抽象数据类型
InitStack(*S):初始化操作,建立一个空栈DestoryStack(*S):弱栈存在,销毁栈ClearStack(*S):将栈清空StackEmpty(S):若栈为空,返回True,否则返回falseGetTop(S,*e):弱栈存在且为非空,用e返回S的栈顶元素 Push(*S,e):若栈S存在,插入新元素e到栈S中并成为栈底元素Pop(*S,*e):删除栈S中栈顶元素,并用e返回元素StackLength(S):返回栈S的元素个数
栈的顺序存储结构及实现
栈的顺序存储结构
下标为0的一端作为栈底,因为首元素都存在栈底,因为首元素都存在栈底,变化小,所以让它作栈底。若存储栈的长度为StackSize,则栈顶位置top必须小于StackSize.当栈存在一个元素是,top等于0,因此常用-1判定条件为top等于-1
对栈操作
Java 中使用LinkedList来模拟栈的操作其中提供了以下方法
addFirst
removeFirst();
addLast();
removeLast();
在栈中,push为入栈操作,pop为出栈操作。
Push用addFirst(),pop用removeFirst(),实现后进先出
用isEmpty() 其父类的方法,判断栈是否为空
用Java来实现栈
public class MyStack{ //定义一个栈类 int[] array; //用int数组来保存数据,根据需要可以更换类型 int s_size; //定义一个游标。 public MyStack(int i){ //定义一个带参数构造器 array=new int[i] //动态定义数组的长度 s_size=0 //默认游标为0 } public MyStack(){ //定义一个默认构造器 this(50); //调用带参数构造器,默认长度为50 } public void push(int i) { //定义压栈方法 arrly[this.s_size]=i;// 将传进去的参数存储到数组中 this.s_size++; //将游标自增 } public int pop(){ //定义弹栈方法,从栈顶取出元素 if(this.s_size!=0){ int t = array[s_size-1] //用中间变量保存栈顶的元素 array[s_size-1]=0 //取完元素将该位置设为0 s_size--; //将游标递减 return t; 返回取出的栈顶元素 }else{ System.out.println("The Stack is Empty"); return 0; } public boolean isEmpthy(){ //判断栈是否为空 return this.s_size==0; } public void printALL{ //打印出栈中所有元素,不是取出 if(!this.isEmpty){ for(int i=this.s_size-1,i>=0,i--){ System.out.println(array[i]) } } }}
两栈共享空间
数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组长度n-1处。这样,两个栈如果增加元素,就是两端点向中间延伸。
/** * Created by gyg on 2017/2/9. * 此类用于模拟两栈共享空间的java实现。 */public class TwoStackShareSpace<T> { private Object[] element; //存放元素的数组 private int stackSize; //定义栈的大小 private int top1; // 定义栈1的栈顶指针 private int top2;// 定义栈2的栈顶指针 /** * 初始化栈 */ public TwoStackShareSpace(int size){ element = new Object[size]; //带参数的构造函数,创建指定大小的数组 stackSize = size; //给栈的大小赋值 top1 = -1; // 定义栈1的栈顶指针,默认为空时为 -1 top2 = size;// 定义栈2的栈顶指针,默认为size的大小。 } /** * 压栈,即在栈中存储数据 *@param i 第几个栈 *@param o 入栈元素 */ public boolean push(int i,Object o){ if(top1+1 == top2){ // 用来判断栈是否已经被栈满的判定条件 throw new RuntimeException("栈满"); } else if(i ==1 ){ //i等于1时表示在第一个栈中插入元素 top1++; // top1这时为-1 ++后为0 element[top1]=o; // 数组中在小标为0的位置加入元素 }else if(i ==2 ){ //i等于2时表示在第二个栈中插入元素 top2--; //top2这时位size的大小, element[top2]=o; //将在第二个栈的栈顶添加元素 } else{ throw new RuntimeException("输入错误"); } return true; } /** * 出栈 * @param i 第几个栈 * @return */// @SuppressWarnings("unchecked") public T pop (int i ){ if(i==1){ if(top1==-1) throw new RuntimeException("栈1为空"); element[top1]=0; //将弹出的栈元素位置置0; return (T)element[top1--]; //返回弹出的元素。 } else if(i ==2){ if(top2==stackSize) throw new RuntimeException("栈2为空"); element[top2]=0; //将弹出的栈元素置0; return (T)element[top2++]; //返回要弹出的元素 }else throw new RuntimeException("输入错误"); } /** * 获取栈顶元素 * @param i * @return */ public T get(int i){ if(i == 1){ if(top1 == -1) throw new RuntimeException("栈1为空"); return (T)element[top1]; }else if(i==2){ if(top2 == stackSize) throw new RuntimeException("栈2为空"); return (T)element[top2]; }else throw new RuntimeException("输入错误"); } /** * 判断栈是否为空 * @param i * @return */ public boolean ifEmpty(int i){ if(i == 1){ if(top1 == -1) //判断栈1是否为空 return true; else return false; }else if(i == 2){ if(top2==stackSize) //判断栈二是否为空 return true; else return false; }else throw new RuntimeException("输入错误"); } /** * 遍历结果 */ public String toString(){ String str1 = "栈1:["; String str2 = "栈2: ["; for(int i=top1;i>=0;i--){ if(i==0) str1 =str1+(T)element[i]; else str1=str1+(T)element[i]+","; } str1+="]"; for(int i=top2;i<stackSize;i++){ if(i == stackSize-1) str2 = str2+(T)element[i]; else str2=str2+(T)element[i]+","; } str2+="]"; return str1+"\n\r"+str2; } public static void main(String args[]) { TwoStackShareSpace tsss = new TwoStackShareSpace(20); //初始化一个栈长度为20; System.out.println("第一个栈:"+tsss.ifEmpty(1)+" : 第二个栈:"+tsss.ifEmpty(2)); tsss.push(1,"张三"); //压栈,在第一个栈中添加元素"张三" tsss.push(1,3); // 压栈,元素加在栈顶 tsss.push(1,"李四");//压栈,元素加在栈顶 tsss.pop(1); //弹栈 tsss.push(2,2); //压栈,在第二个栈中添加元素2 System.out.println(tsss.toString());//遍历输出栈栈中元素 System.out.println("第一个栈:"+tsss.ifEmpty(1)+" : 第二个栈:"+tsss.ifEmpty(2)); }}
栈的链式存储结构及实现
栈的链式存储结构,简称为链栈。
把栈顶放在单链表的头部,另外,都已经有了栈顶在头部了,单链表中的头结点也就失去了意义,通常对于链栈,是不需要头结点的。
对链栈的操作
链栈的进栈push和出栈pop操作都很简单,没有任何循环操作,时间复杂度均为0(1),如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈更好一些。
http://blog.csdn.net/bruce_6/article/details/25125751
栈的应用-递归
递归定义:我们把一个直接调用自己通过一系列的调用语句间接地调用自己的函数,称作递归函数
菲波那切数列实现
1 1 2 3 5 8 13 21 34 55 89 144 .....表中数字构成了一个数列。这个数列有个十分明显的特点:前面相邻两项之和构成了后一项。public class Fbi{ public void demo(int i) { if(i<2){ return i==0?0:1; } return demo(i-1)+demo(i-2);//这里使用递归,调用自己。 } public static void main(String[] args){ int i; for(int i=0;i<40;i++) System.out.println(demo(i)) }}
栈的应用-四则运算表达式求值
一种不需要括号的后缀表达式,我们也把它称为逆波兰表示。
对于 “9+(3-1)* 3+10/2”用后缀表达式为 “9 3 1 - 3 * + 10 2 / + ”规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号就将处于栈顶的两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果
中缀表达式转后缀表达式
我们把平时所用的标准四则运算表达式,即“9+(3-1)*3+10/2”叫做中缀表达式。
中缀表达式“9+(3-1)*3+10/2"转化为后缀表达式“9 3 1 - 3 * + 10 2 / + ”规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分; 若是符号,则判断其与栈顶符号的优先级,是右括号或优先级不高于栈顶符号则栈顶元素一次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止
- 数据结构入门(四)-栈的定义与实现
- 数据结构入门(五)-队列的定义与实现
- 栈的实现--数据结构学习(四)
- 数据结构与算法(3)---Java语言实现:栈的单链表定义
- 实验四 栈和队列的定义与实现(未完成)
- 数据结构——普通树的定义与C++实现
- java 数据结构之栈的实现 (四)
- 数据结构与算法的实现 —— 结点定义与数据结构的选择
- 数据结构与算法(1)---Java语言实现:线性表的单链表定义
- 数据结构与算法(4)---Java语言实现:队列的单链表定义
- 第五章 工作流定义工具的设计与实现(四)
- 算法与数据结构 其四 循环队列的实现
- 数据结构---栈的定义
- 定义栈的数据结构
- 考研数据结构与算法之堆栈的使用(四)链表实现的堆栈
- (数据结构与算法分析 四)------数组循环队列的实现( Java语言描述)
- Redis设计与实现——数据结构(四)
- 数据结构与算法(2)---Java语言实现:线性表的单链表定义:方法补充,实现单链表反转,去重
- import绝对路径问题
- Spring mvc学习总结
- base32 加密
- Adobe Photoshop CC 2017 安装破解教程(千寻制作)
- Spring之旅--Spring管理bean的作用域
- 数据结构入门(四)-栈的定义与实现
- 自学JAVA编程的小总结(一)
- div 动态距离浏览器高度
- 薪资调查研究爬取
- 编程珠玑有感!
- Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
- 中华人民共和国国家工商行政管理总局
- HDU1559(简单动态规划)
- 数据结构入门(五)-队列的定义与实现