数据结构之栈和队列

 我们知道,在数组中,若知道数据项的下标,便可立即访问该数据项,或者通过顺序搜索数据项,访问到数组中的各个数据项。但是栈和队列不同,它们的访问是受限制的,即在特定时刻只有一个数据项可以被读取或者被删除。众所周知,栈是先进后出,只能访问栈顶的数据,队列是先进先出,只能访问头部数据。这里不再赘述。

    栈的主要机制可以用数组来实现,也可以用链表来实现,下面用数组来实现栈的基本操作:

[java] view
plain
 copy

 

  1. public class ArrayStack {  
  2.     private long[] a;  
  3.     private int size; //栈数组的大小  
  4.     private int top; //栈顶  
  5.   
  6.     public ArrayStack(int maxSize) {  
  7.         this.size = maxSize;  
  8.         this.a = new long[size];  
  9.         this.top = -1; //表示空栈  
  10.     }  
  11.       
  12.     public void push(long value) {//入栈  
  13.         if(isFull()) {  
  14.             System.out.println("栈已满!");  
  15.             return;  
  16.         }  
  17.         a[++top] = value;  
  18.     }  
  19.       
  20.     public long peek() {//返回栈顶内容,但不删除  
  21.         if(isEmpty()) {  
  22.             System.out.println("栈中没有数据");  
  23.             return 0;  
  24.         }  
  25.         return a[top];  
  26.     }  
  27.       
  28.     public long pop() { //弹出栈顶内容,删除  
  29.         if(isEmpty()) {  
  30.             System.out.println("栈中没有数据!");  
  31.             return 0;  
  32.         }  
  33.         return a[top--];          
  34.     }  
  35.       
  36.     public int size() {  
  37.         return top + 1;  
  38.     }  
  39.       
  40.     public boolean isEmpty() {  
  41.         return (top == -1);  
  42.     }  
  43.       
  44.     public boolean isFull() {  
  45.         return (top == size -1);  
  46.     }  
  47.       
  48.     public void display() {  
  49.         for(int i = top; i >= 0; i--) {  
  50.             System.out.print(a[i] + " ");  
  51.         }  
  52.         System.out.println("");  
  53.     }  
  54. }  

    数据项入栈和出栈的时间复杂度均为O(1)。这也就是说,栈操作所消耗的时间不依赖于栈中数据项的个数,因此操作时间很短。栈不需要比较和移动操作。

    队列也可以用数组来实现,不过这里有个问题,当数组下标满了后就不能再添加了,但是数组前面由于已经删除队列头的数据了,导致空。所以队列我们可以用循环数组来实现,见下面的代码:

[java] view
plain
 copy

 

  1. public class RoundQueue {  
  2.     private long[] a;  
  3.     private int size;   //数组大小  
  4.     private int nItems; //实际存储数量  
  5.     private int front;  //头  
  6.     private int rear;   //尾  
  7.   
  8.     public RoundQueue(int maxSize) {  
  9.         this.size = maxSize;  
  10.         a = new long[size];  
  11.         front = 0;  
  12.         rear = -1;  
  13.         nItems = 0;  
  14.     }  
  15.       
  16.     public void insert(long value) {  
  17.         if(isFull()){  
  18.             System.out.println("队列已满");  
  19.             return;  
  20.         }  
  21.         rear = ++rear % size;  
  22.         a[rear] = value; //尾指针满了就循环到0处,这句相当于下面注释内容        
  23.         nItems++;  
  24. /*      if(rear == size-1){ 
  25.             rear = -1; 
  26.         } 
  27.         a[++rear] = value; 
  28. */  
  29.     }  
  30.       
  31.     public long remove() {  
  32.         if(isEmpty()) {  
  33.             System.out.println("队列为空!");  
  34.             return 0;  
  35.         }  
  36.         nItems--;  
  37.         front = front % size;  
  38.         return a[front++];  
  39.     }  
  40.       
  41.     public void display() {  
  42.         if(isEmpty()) {  
  43.             System.out.println("队列为空!");  
  44.             return;  
  45.         }  
  46.         int item = front;  
  47.         for(int i = 0; i < nItems; i++) {  
  48.             System.out.print(a[item++ % size] + " ");  
  49.         }  
  50.         System.out.println("");  
  51.     }  
  52.       
  53.     public long peek() {  
  54.         if(isEmpty()) {  
  55.             System.out.println("队列为空!");  
  56.             return 0;  
  57.         }  
  58.         return a[front];  
  59.     }  
  60.       
  61.     public boolean isFull() {  
  62.         return (nItems == size);  
  63.     }  
  64.       
  65.     public boolean isEmpty() {  
  66.         return (nItems == 0);  
  67.     }  
  68.       
  69.     public int size() {  
  70.         return nItems;  
  71.     }  
  72. }  

    和栈一样,队列中插入数据项和删除数据项的时间复杂度均为O(1)。

    还有个优先级队列,优先级队列是比栈和队列更专用的数据结构。优先级队列与上面普通的队列相比,主要区别在于队列中的元素是有序的,关键字最小(或者最大)的数据项总在队头。数据项插入的时候会按照顺序插入到合适的位置以确保队列的顺序。优先级队列的内部实现可以用数组或者一种特别的树——堆来实现。堆可参考第8节内容。这里用数组实现优先级队列。

[java] view
plain
 copy

 

  1. public class PriorityQueue {  
  2.     private long[] a;  
  3.     private int size;  
  4.     private int nItems;//元素个数  
  5.       
  6.     public PriorityQueue(int maxSize) {  
  7.         size = maxSize;  
  8.         nItems = 0;  
  9.         a = new long[size];  
  10.     }  
  11.       
  12.     public void insert(long value) {  
  13.         if(isFull()){  
  14.             System.out.println("队列已满!");  
  15.             return;  
  16.         }  
  17.         int j;  
  18.         if(nItems == 0) { //空队列直接添加  
  19.             a[nItems++] = value;  
  20.         }  
  21.         else{//将数组中的数字依照下标按照从大到小排列  
  22.             for(j = nItems-1; j >= 0; j--) {  
  23.                 if(value > a[j]){  
  24.                     a[j+1] = a[j];  
  25.                 }  
  26.                 else {  
  27.                     break;  
  28.                 }  
  29.             }  
  30.             a[j+1] = value;  
  31.             nItems++;  
  32.         }  
  33.     }  
  34.       
  35.     public long remove() {  
  36.         if(isEmpty()){  
  37.             System.out.println("队列为空!");  
  38.             return 0;  
  39.         }  
  40.         return a[--nItems];  
  41.     }  
  42.       
  43.     public long peekMin() {  
  44.         return a[nItems-1];  
  45.     }  
  46.       
  47.     public boolean isFull() {  
  48.         return (nItems == size);  
  49.     }  
  50.       
  51.     public boolean isEmpty() {  
  52.         return (nItems == 0);  
  53.     }  
  54.       
  55.     public int size() {  
  56.         return nItems;  
  57.     }  
  58.   
  59.     public void display() {  
  60.         for(int i = nItems-1; i >= 0; i--) {  
  61.             System.out.print(a[i] + " ");  
  62.         }  
  63.         System.out.println(" ");  
  64.     }  
  65. }  

    这里实现的优先级队列中,插入操作需要O(N)的时间,而删除操作则需要O(1)的时间。在第8节里将介绍堆来改进插入操作的时间。

时间: 2024-10-21 08:45:52

数据结构之栈和队列的相关文章

c c++-数据结构,栈和队列,问题

问题描述 数据结构,栈和队列,问题 已知Q 是一个非空队列,S 是一个空栈,借助队列和栈的ADT 函数,将队列Q的所有元素逆置 解决方案 数据结构-栈和队列数据结构-栈和队列<数据结构>第三章 栈和队列问题回收站 解决方案二: 将队列元素都出队到栈中,再将栈中的数据入队 解决方案三: http://zhidao.baidu.com/link?url=dOiiECx8cRRi-hWjhDyWkIJoYigGhttDvdFnx28a9RNh35ddFDuTlXCINA7CCIriyrMRlHDUp

浅谈算法和数据结构 一 栈和队列

最近晚上在家里看Algorithems,4th Edition,我买的英文版,觉得这本书写的比较浅显易懂,而且"图码并茂",趁着这次机会打算好好学习做做笔记,这样也会印象深刻,这也是写这一系列文章的原因.另外普林斯顿大学在Coursera 上也有这本书同步的公开课,还有另外一门算法分析课,这门课程的作者也是这本书的作者,两门课都挺不错的. 计算机程序离不开算法和数据结构,本文简单介绍栈(Stack)和队列(Queue)的实现,.NET中与之相关的数据结构,典型应用等,希望能加深自己对这

数据结构:栈和队列的定义和操作

一.栈和队列定义 1).栈 定义: 栈(Stack)是一个后进先出(Last in first out,LIFO)的线性表,它要求只在表尾进行删除和插入操作. 图如下: 特点: 一.栈特殊的线性表(顺序表.链表),它在操作上有一些特殊的要求和限制:栈的元素必须"后进先出". 三.栈的表尾称为栈的栈顶(top),相应的表头称为栈底(bottom) 二.栈的操作只能在这个线性表的表尾进行. 2).队列 定义: 队列是限定只能在表的一端进行插入,在表的另一端进行删除的特殊的线性表. 图如下:

C#数据结构与算法揭秘五 栈和队列_C#教程

这节我们讨论了两种好玩的数据结构,栈和队列. 老样子,什么是栈, 所谓的栈是栈(Stack)是操作限定在表的尾端进行的线性表.表尾由于要进行插入.删除等操作,所以,它具有特殊的含义,把表尾称为栈顶(Top) ,另一端是固定的,叫栈底(Bottom) .当栈中没有数据元素时叫空栈(Empty Stack).这个类似于送饭的饭盒子,上层放的是红烧肉,中层放的水煮鱼,下层放的鸡腿.你要把这些菜取出来,这就引出来了栈的特点先进后出(First in last out).   具体叙述,加下图. 栈通常记

用栈和队列实现虚拟停车场系统

学校的数据结构课程实验之一. 用到的数据结构:栈.队列 需求分析 设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出.汽车在停车场内按车辆到达时间的先后顺序依次排列. 若车场内已停满n辆汽车,则后来的汽车只能在门外便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入:当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,该车开出后,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开时必须按它停留的时间长短交纳费用.   数据要求 要求模拟停车场车辆的管理

数据结构――栈、队列和树(Java)

数据|数据结构 数据结构――栈.队列和树 开发者可以使用数组与链表的变体来建立更为复杂的数据结构.本节探究三种这样的数据结构:栈.队列与树.当给出算法时,出于简练,直接用Java代码. 栈 栈是这样一个数据结构,其数据项的插入和删除(获取)都只能在称为栈顶的一端完成.因为最后插入的数据项就是最先要删除的数据项,开发者往往将栈称为LILO(last-in, first-out)数据结构. 数据项压入(插入)或者弹出(删除或取得)栈顶.图13示例了一个有三个String数据项的栈,每个数据项压入栈顶

数据结构学习(C++)之栈和队列

栈和队列是操作受限的线性表,好像每本讲数据结构的数都是这么说的.有些书按照这个思路给出了定义和实现:但是很遗憾,本文没有这样做,所以,有些书中的做法是重复建设,这或许可以用不是一个人写的这样的理由来开脱. 顺序表示的栈和队列,必须预先分配空间,并且空间大小受限,使用起来限制比较多.而且,由于限定存取位置,顺序表示的随机存取的优点就没有了,所以,链式结构应该是首选. 栈的定义和实现 #ifndef Stack_H #define Stack_H #include "List.h" tem

数据结构实践——停车场模拟(栈和队列综合)

本文是针对数据结构基础系列网络课程(3):栈和队列的实践项目. 设停车场是一个可停放n辆汽车的狭长死胡同,南边封口,汽车只能从北边进出(这样的停车场世间少有).汽车在停车场内按车辆到达时间的先后顺序,最先到达的第一辆车停放在车场的最南端,依次向北排开.若车场内已停满n辆汽车,则后来的汽车只能在门外的候车场上等候,一旦有车开走,则排在候车场上的第一辆车即可开入.当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路(假定停车场内设有供车辆进出的便道,所有的司机也必须在车内随时待命),待

数据结构与算法02 之栈与队列

 我们知道,在数组中,若知道数据项的下标,便可立即访问该数据项,或者通过顺序搜索数据项,访问到数组中的各个数据项.但是栈和队列不同,它们的访问是受限制的,即在特定时刻只有一个数据项可以被读取或者被删除.众所周知,栈是先进后出,只能访问栈顶的数据,队列是先进先出,只能访问头部数据.这里不再赘述.     栈的主要机制可以用数组来实现,也可以用链表来实现,下面用数组来实现栈的基本操作: [java] view plain copy   public class ArrayStack {