数据结构(四)

来源:互联网 发布:好莱坞特效制作软件 编辑:程序博客网 时间:2024/05/17 06:30

 同学说我更新得太慢了。是啊,隔了好久才更新一次。其实我也想快点的更新,更新得越快同时也说明我掌握知识的速度越快,越多。但是工作不允许啊。每天早出晚归,空闲的实现还要分配一点给外语。不过,以后我会努力的,只要有朋友的支持,我会把我的所学和经验奉献给大家。有点开源的精神吧。呵呵,当然了,我还没有哪个资格。

记得,在学校的时候,不论是在课本上,试卷上,还是老师课堂提问。总会不自觉的把栈和队列联系在一起。这充分的说明了栈和队列存在着相似性,同时又有区别。在数据结构(三)中,提到了栈。它是一个后入先出的容器,那么队列又是什么呢?我想,你一定猜到了,队列是先入先出(FIFO)的容器。你看,栈和队列的异同都放在你的面前了。

线性队列和循环队列,是我们者经常使用到两种队列。在两种队列中,数据项都是在队列尾插入,然后移向队列头,并从队列头删除或获取。

为了有助于记忆,我们仍然举一个实际中的例子来说明。给你半分钟想想,什么例子更形象?呵呵!打印机作业,你觉得这个例子怎么样?打印机大家都用过,也知道

它的速度比计算机慢许多,所以操作系统将其打印任务分派给其打印子系统,打印子系统就会将这些任务插入到一个打印队列中。队列中的第一个任务先打印,最后一个任务最后打印。怎么样够形象吧!

      这里以一循环队列为例子。和上一篇文章一样,先创建一个队列的基类,然后再派生出来两个子类,我们用数组和链表来分别实现。

#include "List.h"
#include "Array.h"

template <class T>
class Queue
{
 public:
  virtual T &Head() const = 0;
  virtual void Enqueue(T&) = 0;
  virtual T &Dequeue() = 0;
    protected:
  int nLength;
  int nCount;
};

数组实现方法:

template <class T>
class QueueArray:public Queue<T>
{
 public:
  QueueArray(int nCnt)
  {
   nCount = 0;
   nHead = 0;
   nTail = 0;
   nLength = nCnt;
   pArray = new Array<T>(nCnt);
  }

  ~QueueArray()
  {
   if(NULL != pArray)
   {
    delete pArray;
   }
  }

  T &Head() const
  {
   if(0 == nCount)
   {
    std::domain_error("Queue is empty");
   }
   return (*pArray)[nHead];
  }

  void Enqueue(T &value)
  {
   if(nCount == nLength)
   {
    std::domain_error("Queue is full");
   }
   if(++nTail == nLength)
   {
    nTail = 0;
   }
   else
   {
    --nTail;
   }
   (*pArray)[nTail] = value;
   ++nTail;
   ++nCount;
  }

  T &Dequeue()
  {
   if(0 == nCount)
   {
    std::domain_error("Queue is empty");
   }
   T tResult = (*pArray)[nHead];
   if(nHead == nLength)
   {
    nHead = 0;
   }
   else
   {
    ++nHead;
   }
   --nCount;
   return tResult;
  }
 private:
  Array<T> *pArray;
  int nHead;
  int nTail;
};

链表实现方法:
template <class T>
class QueueList:public Queue<T>
{
public:
 QueueList(int nCnt)
 {
  nCount = 0;
  nLength = nCnt;
  pList = new LinkedList<T>();
 }

 ~QueueList()
 {
  if(NULL != pList)
  {
   delete pList;
  }
 }
 
 T &Head() const
 {
  if(0 == nCount)
  {
   std::domain_error("Queue is empty");
  }
  
  return const_cast<T&> (pList->GetHead()->GetDatum());
 }

    void Enqueue(T &value)
 {
  if(nLength == pList->GetLength())
  {
   std::domain_error("Queue is full");
  }
  pList->Append(value);
  ++nCount;
 }

 T &Dequeue()
 {
  if(0 == nCount)
  {
   std::domain_error("Queue is empty");
  }
  T tRuselt = pList->GetHead()->GetDatum();
  pList->DelElement(1);
  --nCount;
  return tRuselt;
 }
private:
 LinkedList<T> *pList;

};