# 数据结构（九）——队列

## 二、队列的实现

### 1、队列的抽象类

`````` 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;//队列长度
};``````

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

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;
}

{
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);
}
};``````

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

A、类模板实现，继承自抽象父类Queue
B、内部使用链式结构实现元素的存储
C、只在链表的头部和尾部进行操作

`````` template <typename T>
{
protected:
public:
{
}
{
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();
}
};``````

## 三、栈和队列的相互实现

### 1、栈实现队列

``````template <typename T>
class StackToQueue:public Queue<T>
{
protected:
public:
{
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();
}
};``````

### 2、队列实现栈

``````template <typename T>
class QueueToStack:public Stack<T>
{
protected:
//将入队列前n-1个元素移动到出队列
void move()const
{
int n = m_pIn->length() - 1;
for(int i = 0; i < n; i++)
{
m_pIn->remove();//从入队列出队
}
}
//交换
void swap()
{
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)
{
}
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();
}
};``````