. . . . . . . . . . . . . . Blog Garden' C plus plus (My technology Impire!)

................................................................ It‘s a age of economic globalization and Infomation globalization........................................

数据结构复习篇:队列

数据结构复习篇:队列

队列是一种先进先出(FIFO)的线性表。跟栈一样,它们的pop()、push()操作的时间复杂度都为1。同样有两种实现,基于数组的AQueue和链式LQueue的。难点在于基于数组的。为了保证pop()和push()的时间复杂度为1,要用到“循环存储”的思想。这个思想就是把一个固定长度数组看作是一个首尾相接的“圈”。这样,我们的“入队”push()和“出队”pop()操作,就可以直接向队尾加入一个元素或从队首取出一个元素。要在数组中,实现循环存储,需要用到一个小技巧:
例如,已知数组A长度为100,那么,当队尾为A[99]时,如果再执行一个push()操作(前提是,A[0]没有被队首元素占用),那么A[0]将成为新的队尾,怎么告诉计算机当队尾下标为99时,新加入的元素应该放在下标为0的地方而不是100呢?这里用到一个求余运算,可以解决“下标循环”的问题:
设数组长度为Len,队尾下标为rear,那么加入一个元素后,新的队尾下标为:
                                   newRear = (rear+1)%Len
还有一点需要注意,因为队列是可以为空的,这个时候,队首与队尾的下标相等,那么当有一元素的时候,队尾下标指向那个元素的后面那个位置,这就是说,队尾下标所指的那个位置,是不存放元素的,所以数组的长度Len应比队列长度queSize大1。
链式队列很容易理解,我不多说了。
下面是我按照C++标准库中queue的接口,自己写的代码:
/*
定义队列的共公接口
文件名:QueueInterface.h
*/
#ifndef QUEUEINTERFACK_H
#define QUEUEINTERFACK_H

#include 
"NodeInterface.h"
using namespace std;
namespace zyk
{

    
    template
<class T> class Queue
    {
    
public:
        
//从今天开始,我决定采用STL的接口,
        
//这样有利于我们熟悉标准库函数
        virtual T & back() = 0;        //返回队尾元素
        virtual T & front() = 0;    //返回队首元素    
        virtual void pop() = 0;        //出队
        virtual void push(const T&= 0;//进队
        virtual bool empty() = 0;    //返回值指示队列是否为空 
        virtual int size() = 0;        //返回队中元素个数            
    };

    
//基于数组的队列AQueue
    template<class T> class AQueue : Queue<T>
    {
    
private:
        
int maxSize;    //队列的最大容量,由于采用循环存储的方式,
                
//它比实际值大1,以保证队尾rear所指的位置,
                
//是队尾元素的下一个位置 
        int mfront;    //指示队首元素的在数组中的下标
        int mrear;    //队尾元素的在数组中的下标的下一个位置
        T * listArray;    //数组指针

    
public:
        AQueue(
int size = 100)
        {
            maxSize 
= size + 1;    //这一点很关键
            mfront = mrear = 0;
            listArray 
= new T[maxSize];
        }
        
~AQueue()
        {
            delete [] listArray;
        }

        T 
& back()
        {
            
//当rear=0里,(rear-1)%maxSize将会成为负-1,而(mrear-1+maxSize)%maxSize可以解决这个问题
            return listArray[(mrear - 1 + maxSize)%maxSize];    
        }

        T 
& front()
        {
            
return listArray[mfront];
        }
        
        
void pop()
        {
            mfront 
= (mfront+1)%maxSize;
        }
        
void push(const T & item)
        {
            listArray[mrear] 
= item;
            mrear 
= (mrear+1)%maxSize;
        }
        
bool empty()
        {
            
if (mrear == mfront)
                
return true;
            
else return false;
        }
        
int size()
        {
            
return (mrear - mfront + maxSize)%maxSize;
        }

    };

    
//链式队列
    template<class T> class LQueue : Queue<T>
    {
    
private:
        
int queSize;    //队元素的个数
        Node<T> * pfront;    //指向队首元素
        Node<T> * prear;    //指向队尾元素
    public:
        LQueue()
        {
            queSize 
= 0;
            pfront 
= prear = NULL;
        }
        
~LQueue()
        {
            
while (pfront != NULL)
            {
                Node
<T> * tmp;
                tmp 
= pfront;
                pfront 
= pfront->next;
                delete tmp;
            }
        }

        T 
& back()
        {
            
return prear->element;
        }

        T 
& front()
        {
            
return pfront->element;
        }

        
void pop()
        {
            Node
<T> * tmp;
            tmp 
= pfront;    
            
if (queSize == 1)    //只有一个元素.
            {
                prear 
= pfront->next;
            }
            pfront 
= pfront->next;
            delete tmp;            
            
--queSize;
        }
        
void push(const T & item)
        {
            
if (queSize == 0)    //第一个元素入栈,这时情况比较特殊
            {
                pfront 
= prear = new Node<T>(item);    //一同指向第一个元素
                ++queSize;
                
return;
            }
            prear
->next = new Node<T>(item);
            prear 
= prear->next;
            
++queSize;
        }
        
bool empty()
        {
            
if (queSize == 0)
                
return true;
            
else 
                
return false;
        }
        
int size()
        {
            
return queSize;
        }
        
    };
}

#endif

posted on 2006-10-04 03:24 Technical Consultant 阅读(175) 评论(0)  编辑 收藏 引用 所属分类: Algorithm & DataStruct


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


My Links

Blog Stats

常用链接

留言簿(3)

随笔分类(47)

随笔档案(45)

文章分类(87)

文章档案(87)

相册

C++

Database

Game Develope & Game Engine

Java

News

Web

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜