> 设为首页 加入收藏 关于我们
 
 
首页 新闻 技术 教程 框架 源码 服务中心  
 
 
  合作 MyRSS 博客 wiki 社区
 
信息搜索: 全部网站 easyjf.com
  当前位置:首页-参考资料
数据结构系列教程(三)
作者:天意 来源:www.easyjf.com  发布时间:2006-08-17
 

`第三讲 堆栈和队列

堆栈和队列都是特殊的线性表,他们的逻辑关系完全相同,差别是线性表的插入和删除操作不受限制,而堆栈只能在栈顶插入和删除,队列只能在队尾插入、队头删除,堆栈和队列都可以分别用顺序储存结构和链式存储结构,堆栈的操作主要有入栈、出栈、取栈顶元素、是否为空,可以设计通用接口Stack..ava如下:

 

/**

 * @author 张钰

 *

 */

public interface Stack {

    public void push(Object obj) throws Exception;//把数据元素obj插入堆栈

    public Object pop()throws Exception;//出栈,删除栈顶元素并返回

    public Object getTop()throws Exception;//获取栈顶元素

    public boolean notEmpty();//判断是否为空

}

下面就不同的结构展开:

()顺序堆栈

   具有顺序储存结构的堆栈称为顺序堆栈,顺序堆栈和顺序表的数据成员是相同的,只是顺序堆栈的入栈和出栈操作只能在当前栈顶进行,其结构可以参考下图:

栈底                                栈顶

a0

a1

a2

a3

a4

 

 

satck                                         top=5             maxStackSize-1

 

stack表示顺序堆栈储存数据的数组,a0a1等表示已经入栈的数据,a0a1先入栈,maxStackSize表示顺序堆栈数组stack的最大元素个数,top表示顺序堆栈的stack的当前栈顶的下标,设计顺序堆栈类如下SeqStack.java

 

 

/**

 * @author 张钰

 *

 */

public class SeqStack implements Stack {

 

       /*

        * @see Stack#push(java.lang.Object)

        */

    final int defaultSize=10;

    int top;

    Object[] stack;

    int maxStackSize;

    public SeqStack(){

           initiate(defaultSize);

    }

    public SeqStack(int sz){

           initiate(sz);

    }

       private void initiate(int sz) {

              // 初始化

              maxStackSize=sz;

              top=0;

              stack=new Object[maxStackSize];

       }

       public void push(Object obj) throws Exception {

              // 插入堆栈

         if(top==maxStackSize){

                throw new Exception("堆栈已满!");

         }

         stack[top]=obj;

         top++;

       }

 

       /*

        * @see Stack#pop()

        */

       public Object pop() throws Exception {

              // 出栈

              if(top==0){

                     throw new Exception("堆栈已空!");

              }

              top--;

              return stack[top];

       }

 

       /*

        * @see Stack#getTop()

        */

       public Object getTop() throws Exception {

              // 获取栈顶数据

              if(top==0){

                     throw new Exception("堆栈已空!");

              }

              return stack[top-1];

       }

 

       /*

        * @see Stack#notEmpty()

        */

       public boolean notEmpty() {

              // 判断是否为空

              return (top>0);

       }

 

}

() 链式堆栈

链式堆栈具有链式存储结构,用节点构造链,,每个节点由两个域组成,一个是存放数据元素的域element,另一个是存放下一个节点的对象引用域也就是指针域next,堆栈有两端,插入数据和删除元素的一端为栈顶,另一端为栈底,链式堆栈都不带头节点(大家可以思考一下为什么?),链式堆栈类的设计LinStack.java

public class LinStack implements Stack{

Node head;//堆栈头

int size;//节点个数

public void LinStack(){

head=null;

size=0;

}

public void push(Object obj){//入栈

head=new Node(obj,head);//新节点为栈顶

}

public Object pop() throws Exception{ //出栈

if(size==0){

throw new Exception(“堆栈已空”);

}

Object obj=head.element;//取原栈顶元素

head=head.next;//原栈顶节点脱链

Size--;

Return obj;

}

public Boolean notEmpty(){

return head!=null; //是否空

}

public Object getTop(){

return head.element; //取栈顶元素

}

}

,堆栈由于其操作的特殊性而存在,在很多地方能起到独特的作用,比喻中缀表达式转换成后缀表达式,编译软件中的括号匹配问题(eclipse中就很好)都是使用堆栈的特殊性来设计算法,具体的问题大家可以和我一起交流!

 

下面讲讲队列,队列的特点就是从队尾插入、队头删除,也是一种特殊的线性表,队列的操作和堆栈一样主要有:入队列、出队列、取队头数据元素、是否为空,队列的接口类Queue.java可以设计如下:

/**

 * @author 张钰

 *

 */

 

public interface Queue{

public void append(Object obj) throws Exception;

public Object delete()throws Exception;

public Object getFront() throws Exception;

public Boolean notEmpty();

}

()顺序队列

具有顺序结构的队列就叫顺序队列,顺序队列存在假溢出问题,就是一个队列最大存储为6个元素,现在有a0 a1 a2 a3 a4 a5六个元素入队列了,然后又有a0 a1 a2三个元素出队列了,这样剩下的三个元素占据的还是队列的后三个位置,这时候要是有新的元素入队列就会出现数组越界,而事实上队列没有满,这就是假溢出问题,出现问题的原因就是队尾rear和队头front的值不能由所定义数组下界值自动转化成上界值而产生的,解决的办法就是把顺序队列所使用的储存空间构造成一个逻辑上首尾相连的循环队列,当队尾rear和队头front达到maxSize-1后,再自加1自动到0,这样就不会出现队列数组头部已空但队尾因数组下标越界而引起的溢出的假溢出问题,解决顺序循环队列的队列满和队列空状态判断问题通常三种方法:

   1.少用一个储存空间,以队尾rear1等于队头front为队列满的判断条件,即此时队列满的判断条件为:(rear+1)%maxSize=front,队列空的条件为:rear=front

   2.设置一个标志位,添加一个标志位,设标志位为tag,初始时置tag=0,每当入队列操作成功时就置tag=1,出队列操作成功时标志tag=0,那么此时队列满的判断条件是:

rear= =front && tag= =1,队列空的判断条件是:rear==front && tag= =0

   3.设置一个计数器,添加一个计数器count,初始count=0,每当入队列操作成功时count1,每当出队列操作成功count1,这样计数器不仅有标示功能还有计数功能,此时判断队列满的条件是:count>0 && rear= =front,队列空的条件是:count= =0

上面三种方法很明显最好的是第三种使用计数器的方法,采用这种计数器的办法可以设计顺序循环队列的类SeqQueue.java如下:

   public class SeqQueue implements Queue{

      static final int defaultSize=10;

      int front;

      int rear;

      int count;

      int maxSize;

      Object[] data;

      public SeqQueue(){

     initiate(defaultSize);

}

public SeqQueue(int sz){

 initiate(sz);

}

public void initiate(int sz){

  maxSize=sz;

  front=rear=0;

  count=0;

  data=new Object[sz];

}

public void append(Object obj) throws Exception{

   if(count>0 && front= =rear){

throw new Exception(“队列已满!”);

}

data[rear]=obj;

rear=(rear+1)%maxSize;

count++

}

public Object delelte() throws Exception{
         if(count= =0){

    throw new Exception(“队列已空!”);

}

Object temp=data[front];

front=(front+1)%maxSize;

count- -

return temp;

}

public Object getFront() throws Exception{

    if(count= =0){

    throw new Exception(“队列已空”);

}

return data[front];

}

public Boolean notEmpty(){

   return count!=0;

}

}

以上就是顺序队列的java表示,大家可以自己做些例子测试一下,队列还有一种就是链式队列,链式队列就是具有链式结构的队列,链式队列通常设计成不带头节点的结构,结合以前的链式表可以很容易设计出链式队列的类,这个任务就留给大家了,如果有什么疑问的话可以到我们的论坛咨询(http://www.easyjf.com/bbs),队列就是一种从队尾进入队头删除的特殊的顺序表,设计时还考虑了一种优先级队列,就是给队列中的每个元素添加一个优先级标示,出队列时按优先级从高到低的顺序进行,这就是优先级队列,在系统进程管理中的应用很广泛,这个优先级队列这里不做过多的阐述,有兴趣的同学可以研究研究,也可以和我一起探讨!下一讲:串!
评论】 【加入收藏】 【推荐给朋友】 【字体:  】 【关闭 
 
团队常用资源链接
《EasyJF办公室及联系方式》
《如何参与EasyJF开源工作》
EasyJF协同及版本控制-SVN
《EasyJF团队章程》
《EasyJF团队成员工作手册》
《EasyJF成员名单》
《EasyJF项目列表》
《EasyJF开源基金赞助名单》
 
 
EasyJWeb
EasyJWeb是基于
java技术,应用于
WEB应用程序快速
开发的MVC框架,
框架设计构思来源于国内众多项
目实践,框架旨在借鉴当前主要
流行的开源Web框架(Struts、
JSF、Tapestry 、Webwork),吸
取其优点及精华,利用
Velocity作为模板页面引擎,实
现页面及代码完全分离的MVC开发
取框架。
EasyJF开源CMS
EasyJF开源CMS
有常用CMS系统的
基本功能,另外还
有自动html文件生
成、AJAX级联菜单、积分系统、
权限管理等功能,支持UBB。该论
坛系统使用基于OO的方法设计,
采用多层B/S构架,数据库持久层
使用Hibernate,Web层使用
Struts框架,java代码与页面
完全分离,易扩展。
EasyJF开源博客系统
EasyJF开源博客系
统基本的博客的书
写、博客圈、流量
统计、排名、个人
像册、音乐、专题等功能。支持
自定义模板、静态html文件生成
、服务器集群、权限系统、积分
系统等。系统使用基于OO的方法
设计,采用多层B/S构架,数据库
持久层使用EasyDBO,Web层使用
EasyJWeb框架,java代码与页面
完全分离,易扩展。
EasyDBO
EasyDBO是一个非
常适合中小型软件
数据库开发的数据
持久层框架,系统
参考hibernate、JDO等,结合中
小项目软件的开发实际,实现简
单的对象-关系数据库映射。
友情连接
Java研究组织(JR)  与JAVA共舞  java视野   Java开源大全   BlogJava      Jdon解道 SpringSide   天乙论坛   CowNew开源团队  AgileJava开源   javathinker   CSDN Java频道  赛迪网Java频道  
中国Eclipse社区   Java家   Java中文站 FireFox中锁文网   java天下   ideagrace   解惑

Copyright (C) 2005 EasyJF.com, All Rights Reserved
版权所有 简易java框架网
渝ICP备06004507号 如有意见请与我们联系 Powered by EasyJFramework