博客
关于我
浅谈栈和队列
阅读量:452 次
发布时间:2019-03-06

本文共 5826 字,大约阅读时间需要 19 分钟。

栈模型

栈(stack)是限制对元素的插入(push)和删除(pop)只能在一个位置上进行的表,该位置是表的末端,叫做栈的栈顶(top)。

栈的基本操作只有两种,压入栈(push)和弹出栈顶(pop),且只能作用于栈顶。(只有栈顶元素是可访问的

你可以把栈结构理解成一个底部封闭,顶部打开的桶。最先进去的元素一定是最后才能取出,最晚进去的元素一定是最先取出。

因此栈又叫做LIFO(后进先出,Last In First Out)表。

栈的优势

栈的操作是常数时间的,而且是以非常快的常数时间。在某些机器上,push和pop都可以写成一条机器指令,现代计算机把栈操作作为它指令的一部分。因此栈是在计算机科学中继数组之后最基本的数据结构。

栈的实现

栈的实现分为数组实现和链表实现。

  1. 链表实现
    这里我们使用单链表来实现,定义一个first指针指向栈顶,栈的链表实现实际上是简化了单链表实现,具体实现看以下代码。
1public class StackImplementByLinklist
 { 2    public Node
 first; 3    int size; 4    //内部类定义node 5    public class Node
{ 6        AnyType data; 7        Node
 next; 8    } 9     //初始化 10    public void stack(){ 11        first=null; 12        size=0; 13    } 14 15    public void push(AnyType a){ 16        Node oldNode=first; 17        first=new Node(); 18        first.data=a; 19        first.next=oldNode; 20        size++; 21    } 22 23    public AnyType pop(){ 24        AnyType a=first.data; 25        first=first.next; 26        size--; 27        return a; 28    } 29 30    public boolean isEmpty(){ 31        return size==0; 32    } 33 34    public int size(){ 35        return size; 36    } 37}
  1. 数组实现
    相比于链表实现,数组实现栈更加的常用。因为数组操作的常数时间极短,而且实现起来更加简单。
1public class StackImplementByArray
 { 2    AnyType[] arr; 3    int size; 4    public void stack(int capacity){ 5        arr=(AnyType[])new Object[capacity]; 6        size=0; 7    } 8    public void push(AnyType a){ 9        if(size==arr.length){ 10            changeArray(2*size+1); 11        } 12        arr[size]=a; 13        size++; 14    } 15    public AnyType pop(){ 16        if(size==0){ 17            System.out.println("栈顶为空"); 18            System.exit(0); 19        } 20        AnyType a=arr[size-1]; 21        arr[size-1]=null; 22        size--; 23        return a; 24    } 25    public boolean isEmpty(){ 26        return size==0; 27    } 28    public int size(){ 29        return size; 30    } 31 32    //由于数组大小是要先确定的,因此当数组满了后要扩大数组容量 33    public void changeArray(int newCapacity){ 34        AnyType[] newArr=(AnyType[])new Object[newCapacity]; 35        for(int i=0;i

栈的应用

  • 平衡符号的检测

编译器检查程序符号的语法错误,常常就是通过栈来实现的。

在编程时,我们经常会用到“ ( ),[ ],{ }," " ”这些符号,当这些符号不是配对出现的,编译器就会报错,编译就无法通过。

那么,编译器是怎么知道这些符号有没有配对出现的呢?它通常是这么处理的。

当遇到左符号,如“( [ { " ”这些,就把它压入一个准备好的栈;否则就弹出栈顶,检测当前符号是否与栈顶元素配对。一旦不能配对,直接退出报错。

  • 算术表达式的求值

队列

队列模型

wiki: 队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。

队列模型就相当于我们日常生活的排队,在队伍的后面入队,在队伍的前端出队。

多种队列

队列一般分为普通的数组队列,链表队列和循环队列。

链表队列:长度一般是无限的,一般不存在溢出的可能性,用完就销毁,不会浪费内存空间。

普通的数组队列:长度一般是有限的,即数组长度。由于元素出队后其位置的内存空间并不会释放,因此会浪费大量的内存空间。

循环队列:特殊的数组队列,由于普通的数组的队列会浪费大量的内存空间,因此出现了循环队列。当循环队列的队尾指针到达数组末尾后,会重新回到数组起始位置,实现了对内存的重复利用。

队列的实现

1.链表队列

1public class QueueImplementByLinkList
 { 2    Node first;//队首 3    Node last;//队尾 4    int size; 5    public class Node{ 6        AnyType data; 7        Node next; 8        public Node(AnyType data,Node next){ 9            this.data=data; 10            this.next=next; 11        } 12    } 13 14    //初始化队列 15    public void initqueue(){ 16        first=new Node(null,null); 17        last=first; 18        size=0; 19    } 20 21    //入队 22    public void enqueue(AnyType a){ 23        if(size==0){ 24            last.data=a; 25            size++; 26            return; 27        } 28        Node oldlast=last; 29        last=new Node(a,null); 30        oldlast.next=last; 31        size++; 32    } 33 34    //出队 35    public AnyType dequeue(){ 36        if(size==0){ 37            System.out.print("队列为空"); 38            System.exit(0); 39        } 40        AnyType a=first.data; 41        first=first.next; 42        size--; 43        return a; 44    } 45    public boolean isEmpty(){ 46        return size==0; 47    } 48    public int size(){ 49        return size; 50    } 51}

2.数组队列

1public class QueueImplementByArray
 { 2    AnyType[] arr; 3    int first; 4    int last; 5    int size; 6    //初始化 7    public void ininqueue(int capacity){ 8        arr=(AnyType[])new Object[capacity]; 9        first=0; 10        last=0; 11        size=0; 12    } 13    public void enqueue(AnyType a){ 14        if(size==arr.length){ 15            changeArray(2*size+1); 16        } 17        arr[last++]=a; 18        size++; 19    } 20    public AnyType dequeue(){ 21        if(size==0){ 22            System.out.println("队列为空"); 23            System.exit(0); 24        } 25        AnyType a=arr[first++]; 26        arr[first-1]=null; 27        size--; 28        return a; 29    } 30    public void changeArray(int newCapacity){ 31        AnyType[] newArr=(AnyType[])new Object[newCapacity]; 32        for(int i=0;i
  1. 循环队列
1public class CycleQueue {  2    int[] arr;  3    int start;//队首  4    int end;//队尾  5    int size=0;  6    //初始化  7    public void initqueue(int size){  8        arr=new int[size];  9        size=0; 10        start=0; 11        end=0; 12    } 13 14    //入队 15    public void enqueue(int num){ 16        if(size>arr.length){ 17            System.out.println("队列已满"); 18            return; 19        } 20        if(end==arr.length){ 21            end=0; 22        } 23        arr[end++]=num; 24        size++; 25    } 26 27    //出队 28    public int dequeue(){ 29        if(size==0){ 30            System.out.println("队列为空"); 31            System.exit(0); 32        } 33        if(start==arr.length){ 34            start=0; 35        } 36        size--; 37        return arr[start++]; 38    } 39 40    public boolean isEmpty(){ 41        return size==0; 42    } 43    public int size(){ 44        return size; 45    } 46}

一点点总结

栈和队列是基本的数据结构,是对数组和链表的重新封装和扩展。由于它们的特性和执行速度,栈和队列被广泛的使用。

最后,不要为了使用数据结构而使用使用数据结构,要区分各种数据结构的使用场景,灵活地运用数据结构,可以事半功倍。

如果这篇文章对你有帮助的话,左下角给个推荐鸭,这个对我真的很重要?!

转载地址:http://cfjfz.baihongyu.com/

你可能感兴趣的文章
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>
mysql 死锁(先delete 后insert)日志分析
查看>>
MySQL 死锁了,怎么办?
查看>>