数据结构(九)——队列

数据结构(九)——队列

1、队列简介

队列是一种特殊的线性表,仅能在两端进行操做,队头能够进行区数据操做,队尾进行插入数据操做。
队列的特性是先进先出。
数据结构(九)——队列
队列的操做包括建立队列、销毁队列、入队、出队、清空队列、获取队头元素、获取队列的长度。数组

2、队列的实现

一、队列的抽象类

template <typename T>
  class Queue:public Object
  {
  public:
    virtual void add(const T& value) = 0;//进队列
    virtual void remove() = 0;//出队列
    virtual T front()const = 0;//获取队头元素
    virtual void clear() = 0;//清空队列
    virtual int length()const = 0;//队列长度
  };

二、队列的顺序存储结构实现

队列能够使用顺序存储结构的内存空间实现,其内存空间分布以下:
数据结构(九)——队列
根据存储空间的分配方式能够分为使用原生数组实现的静态队列和使用动态分配的堆空间实现的动态队列。
静态队列的实现要点以下:
A、类模板实现
B、使用原生数组做为队列的存储空间
C、使用模板参数决定队列的容量大小
静态队列的实现以下:数据结构

template <typename T, int N>
  class StaticQueue:public Queue<T>
  {
  protected:
    T m_space[N];//队列存储空间,N为模板参数
    int m_front;//队头标识
    int m_rear;//队尾标识
    int m_length;//队列长度
  public:
    StaticQueue()
    {
      m_front = 0;
      m_rear = 0;
      m_length = 0;
    }

    int capacity()const
    {
      return N;
    }

    void add(const T &value)//入队
    {
      if(m_length < N)
      {
          m_space[m_rear] = value;
          m_rear = (m_rear + 1) % N;
          m_length++;
      }
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No enough memory...");
      }
    }

    void remove()//出队
    {
      if(m_length > 0)
      {
          m_front = (m_front + 1) % N;
          m_length--;
      }
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No element...");
      }
    }

    T front() const//取队头元素
    {
      if(m_length > 0)
      {
          return m_space[m_front];
      }
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No element...");
      }
    }
   void clear()//清空队列
   {
     m_length = 0;
     m_front = 0;
     m_rear = 0;
   }

   int length() const
   {
     return m_length;
   }
   bool isEmpty()const
   {
     return (m_length == 0) && (m_front == m_rear);
   }

   bool isFull()const
   {
     return (m_length == N) && (m_front == m_rear);
   }
  };

静态队列的缺陷:
当存储的元素类型为类类型时,建立静态队列时会屡次调用元素类型的类构造函数,影响效率。ide

三、队列的链式存储结构实现

队列使用链式存储结构实现的内容空间分布以下:
数据结构(九)——队列
链式队列的实现要点:
A、类模板实现,继承自抽象父类Queue
B、内部使用链式结构实现元素的存储
C、只在链表的头部和尾部进行操做
链式队列的实现:函数

template <typename T>
  class LinkedQueue:public Queue<T>
  {
  protected:
    LinkedList<T> m_list;
  public:
    LinkedQueue()
    {
    }
    void add(const T& value)//入队
    {
      m_list.insert(value);
    }

    void remove()//出队
    {
      if(m_list.length() > 0)
         m_list.remove(0);
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No enough memory...");
      }
    }
    T front()const//获取队头元素
    {
      if(m_list.length() > 0)
         return m_list.get(0);
      else
      {
          THROW_EXCEPTION(InvalidOperationException, "No elemnet...");
      }
    }

    void clear()//清空队列
    {
      m_list.clear();
    }

    int length() const
    {
      return m_list.length();
    }
  };

3、栈和队列的相互实现

一、栈实现队列

用栈实现队列,用栈的后进先出的特性实现队列的先进先出的特性。
用栈实现队列须要使用两个栈,解决方案以下:
数据结构(九)——队列
新元素入队时,将元素压入stack_in栈,spa

template <typename T>
class StackToQueue:public Queue<T>
{
protected:
  mutable LinkedStack<T> m_stack_in;
  mutable LinkedStack<T> m_stack_out;
public:
  void add(const T& value)//入队
  {
    m_stack_in.push(value);
  }
  void remove()//出队
  {
    //出栈为空,则将入栈的全部元素压入出栈并弹出入栈的元素
    if(m_stack_out.size() == 0)
    {
        while(m_stack_in.size() > 0)
        {
            m_stack_out.push(m_stack_in.top());
            m_stack_in.pop();//弹出入栈的元素
        }
    }
    //出栈不为空,将出栈栈顶元素弹出
    if(m_stack_out.size() > 0)
    {
        m_stack_out.pop();
    }
    else
    {
        THROW_EXCEPTION(InvalidOperationException, "No element...");
    }
  }
  T front() const
  {
    if(m_stack_out.size() == 0)
    {
        while(m_stack_in.size() > 0)
        {
            m_stack_out.push(m_stack_in.top());
            m_stack_in.pop();
        }
    }
    //弹出出栈栈顶元素
    if(m_stack_out.size() > 0)
    {
        return m_stack_out.top();
    }
    else
    {
        THROW_EXCEPTION(InvalidOperationException, "No element...");
    }
  }

  void clear()
  {
     m_stack_in.clear();
     m_stack_out.clear();
  }

  int length()const
  {
     return m_stack_in.size() + m_stack_out.size();
  }
};

二、队列实现栈

用队列实现栈,用队列的先进先出的特性实现栈的后进先出的特性。
用队列实现栈须要使用两个队列,解决方案以下:
数据结构(九)——队列code

template <typename T>
class QueueToStack:public Stack<T>
{
protected:
  LinkedQueue<T> m_queue1;
  LinkedQueue<T> m_queue2;
  LinkedQueue<T>* m_pIn;//入队列
  LinkedQueue<T>* m_pOut;//出队列
  //将入队列前n-1个元素移动到出队列
  void move()const
  {
    int n = m_pIn->length() - 1;
    for(int i = 0; i < n; i++)
    {
        m_pOut->add(m_pIn->front());
        m_pIn->remove();//从入队列出队
    }
  }
  //交换
  void swap()
  {
    LinkedQueue<T>* temp = NULL;
    temp = m_pIn;
    m_pIn = m_pOut;
    m_pOut = temp;
  }
public:
  QueueToStack()
  {
    m_pIn = &m_queue1;
    m_pOut = &m_queue2;
  }
  //压栈
  void push(const T& value)
  {
    m_pIn->add(value);//将元素入队列
  }
  void pop()//出栈
  {
    if(m_pIn->length() > 0)
    {
        move();//移动前n-1个元素
        m_pIn->remove();//将入队列的最后一个元素出队
        swap();//交换
    }
    else
    {
        THROW_EXCEPTION(InvalidOperationException, "No element...");
    }
  }

  void clear()
  {
    m_queue1.clear();
    m_queue2.clear();
  }

  T top() const
  {
    if(m_pIn->length() > 0)
    {
        move();//移动
        return m_pIn->front();
    }
    else
    {
        THROW_EXCEPTION(InvalidOperationException, "No element...");
    }
  }

  int size()const
  {
    return m_queue1.length() + m_queue2.length();
  }
};
相关文章
相关标签/搜索