栈、队列和优先队列

一、栈(stack)

    栈只允许访问一个数据项:即最后插入的数据项,删除这个数据项后才能访问到倒数第二个插入的数据项。实现后进先出(LIFO) 的功能。它可以用来检验源程序中的大小中括号是否匹配、解析算术表达式等问题。
    
邮政模拟例
    许多人在工作收到信后,会随手将它放在大厅桌子上的信堆上,等有空的时候就会从上到下处理这些堆积的邮件,这些人的邮件系统就如计算机中的栈。如果他们不遵循这种从上到下的顺序,而先拿堆底的邮件,从下到上,这就和计算机中的优先级队列结构相似。
 
    
栈的定义
  (1)通常称插入、删除的这一端为栈顶(Top),另一端称为栈底(Bottom)。
  (2)当表中没有元素时称为空栈
  (3)栈为后进先出(Last In First Out)的线性表,简称为LIFO表
  栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除。

Stack主要功能
    Push(入栈:压入栈顶)
    Pop(出栈:移除栈元素)
    Peek(查看栈顶元素)是栈的最主要的操作。

栈的操作图如下:
  Data <wbr>Structures <wbr>& <wbr>Algorithms <wbr>in <wbr>Java <wbr>4栈和队列

栈的Java代码
package com.wei;
public class Stack
{
     private int maxSize;      // size of stack array
     private long[] stackArray;  //使用数组实现栈。
     private int top;            // top of stack,栈项数组下标
     
     public Stack(int maxSize) 
     {        
        this.maxSize = maxSize;            
        stackArray = new long[maxSize];  
        top = -1;              
     }
     
     public void push(long value) throws Exception
     {   
        if( isFull() )
   		 throw new Exception("Array is full,cannot be push");
        
        stackArray[++top] = value; 
     }
     
     public long pop() throws Exception
     {    
    	 if( isEmpty() ) 	
    		 throw new Exception("Array is isEmpty,cannot be pop");
         else 
        	 return stackArray[top--];
     }
     
     public long peek() throws Exception 
     {         
    	if( isEmpty() ) 	
    		 throw new Exception("Array is isEmpty,cannot be pop");
       	return stackArray[top];
     }
     
    public Boolean  isFull()
	{
		return (top == maxSize-1);
	}
    
    public Boolean  isEmpty()
  	{
  		return (top == -1);
  	}
}

栈的实例1:单词逆序
     理念:把单词一个一个字母压入栈,再一个一个取出来,单词的字母就逆序了。

栈的实例2:分隔符匹配
     在代码编译器中,解析大小中括号,双引号是否匹配。理念:从字符串中不断地读取字符串,若发现它是左分隔符,将它压入栈中,当讲到一个右分隔符时,弹出栈顶的左分隔符,查看它是否匹配,如果不匹配程序报错。当读完字符串,栈中还有数据项程 序报错。
 
栈的效率
     在StackX类中实现的栈,数据项入栈和出栈的时间复杂度都为常数O(1)


二、队列(queue)
      队列是一种与栈类似的数据结构,不过队列中第一个插入的数据项会最先被移除,即先进先出(FIFO),而栈是最后插入的数据项最  先移除,是后进先出(LIFO)

队列定义
   队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表
  (1)允许删除的一端称为队头(top)
  (2)允许插入的一端称为队尾(bottom)
  (3)当队列中没有元素时称为队列
  (4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表

Queue主要功能
    Insert(入栈:压入栈顶)
    Remove(出栈:移除栈元素)
    Peek(查看栈顶元素)是栈的最主要的操作。


队列的操作图示:
  Data <wbr>Structures <wbr>& <wbr>Algorithms <wbr>in <wbr>Java <wbr>4栈和队列

环绕式处理
     为了避免队列不满却不能插入新数据项的问题(使用数组实现,数组后端已满,但数组的前头由于出队腾出了空间),可以让队头 队尾指针绕回到数组开始的位置(实现方法,每出/入队一个,队头/队尾指针下标加1,下标等于数组大小时指针又指向0)。

队列的Java代码
package com.wei;

public class Queue
{
 private int maxSize;    //数组长度
 private long[] queArray;
 private int top;        //队头指针
 private int bottom;     //队尾指针
 private int nItems;     //个数
 
 public Queue(int maxnum)
 {         
    this.maxSize = maxnum;
    queArray = new long[maxSize];
    top = 0;
    bottom = -1;
    nItems = 0;
 }
 
 public void insert(long value) throws Exception
 {   
    if( isFull() )
    	throw new Exception("queArray is full!");
    if(bottom == maxSize-1) //循环位置
    	bottom = -1;
    	
    queArray[++bottom] = value;
    nItems++;
 }
 
 public long remove() throws Exception
 {       
    if( isEmpty() )
    	throw new Exception("queArray is empty!");
    
    long temp=queArray[top++];
    nItems--;
    if(top==maxSize) //循环位置
    	top=0;
    return temp;
 }
 
 public long peek() throws Exception
 {     
	 if( isEmpty() )
	    	throw new Exception("queArray is empty!");
	 return queArray[top];
 }
 
 public Boolean  isFull()
 {
	 return (nItems == maxSize);
 }
    
 public Boolean  isEmpty()
 {
   return (nItems == 0);
 }
 
}

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


三、优先级队列
     在优先级队列中,数据项按关键字的值有序,这样关键字最小(或最大)的数据项总是在队头。在抢先式多任务操作系统中,程序  排列在优先级队列中,这样优先级最高的程序会先得到时间片并得以运行。优先级队列还应该可以实现相当快的插入数据项,本  章使用数组来实现优先级队列,这种方式插入比较慢。在后继章的堆中,会讲解用堆来实现优先级队列,这种方式插入比较快。

Priority
     实现的机制:每插入一个数据都保证实现优先级队列的内部数组中的数据是有序的,这样每出弹出队列的头的关键字都是最大(小)  的。
优先队列操作图
  Data <wbr>Structures <wbr>& <wbr>Algorithms <wbr>in <wbr>Java <wbr>4栈和队列
优先级队列的Java代码

优先级队列的效率
     用数组实现的优先级队列,插入操作需要O(N)的时间,而删除则需要O(1)的时间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值