数据结构之——《队列》
1.队列
队列:是一种先进先出(FIFO)的线性表,允许在表的一端进行插入(即入队),在表的另一端进行删除(即出队)。
入队:队尾(rear)插入;
出队:队头(front)删除;
2.队列接口实现
(1)定义队列结构体
代码如下(示例):
typedef int QDataType;
typedef struct QNode
{
struct QNode* _next;
QDataType _data;
}QNode;
typedef struct Queue
{
QNode* _front;
QNode* _rear;
int _size;
}Queue;
(2)队列初始化
代码如下(示例):
void queueInit(Queue* q)
{
q->_front = q->_rear = NULL;
q->_size = 0;
}
(3)创建结点
代码如下(示例):
QNode* creatNode(QDataType data)
{
QNode* node = (QNode*)malloc(sizeof(QNode));
node->_data = data;
node->_next = NULL;
return node;
}
(4)入队(尾插)
代码如下(示例):
void queuePush(Queue* q, QDataType data)
{
QNode* node = creatNode(data);
if (q->_front == NULL)
q->_front = q->_rear = node;
else
{
q->_rear->_next = node;
q->_rear = node;
}
++q->_size;
}
(5)出队(头删)
代码如下(示例):
void queuePop(Queue* q)
{
if (q->_front)
{
QNode* next = q->_front->_next;
free(q->_front);
q->_front = next;
//删除之后是否为空队列
if (q->_front == NULL)
q->_rear = NULL;
--q->_size;
}
}
(6)获取队尾元素
代码如下(示例):
QDataType queueBack(Queue* q)
{
return q->_rear->_data;
}
(7)获取队头元素
代码如下(示例):
QDataType queueFront(Queue* q)
{
return q->_front->_data;
}
(8)队列的大小
代码如下(示例):
int queueSize(Queue* q)
{
return q->_size;
}
(9)判断队列是否为空
代码如下(示例):
int queueEmpty(Queue* q)
{
if (q->_front == NULL)
return 1;
return 0;
}
(10)销毁队列
代码如下(示例):
void queueDestroy(Queue* q)
{
QNode* cur = q->_front;
while (cur)
{
QNode* next = cur->_next;
free(cur);
cur = next;
}
q->_front = q->_rear = NULL;
q->_size = 0;
}
3.应用案例:用一个队列实现栈
根据第二部的定义实现的队列接口函数,则用队列实现栈的功能就容易多了。 入栈:队列的入队操作。 出栈:除过最后一个元素,队列中其他元素循环进行出队入队操作,最后一个元素只出队。 获取栈顶元素:队尾元素的获取。 栈是否为空:队列是否为空。typedef struct {
Queue q;
} MyStack;
MyStack* myStackCreate(){
MyStack* ms = (MyStack*)malloc(sizeof(MyStack));
queueInit(&ms->q);
return ms;
}
(1)入栈
void myStackPush(MyStack* obj, int x)
{
queuePush(&obj->q, x);
}
(2)出栈
int myStackPop(MyStack* obj)
{
int ret;
int size = queueSize(&obj->q);
while (size > 1)
{
int front = queueFront(&obj->q);
queuePop(&obj->q);
queuePush(&obj->q,front);
--size;
}
ret = queueFront(&obj->q);
queuePop(&obj->q);
return ret;
}
(3)获取栈顶元素
int myStackTop(MyStack* obj)
{
return queueBack(&obj->q);
}
(4)栈是否为空
int myStackEmpty(MyStack* obj)
{
return queueEmpty(&obj->q);
}
(5)栈释放
void myStackFree(MyStack* obj)
{
queueDestroy(&obj->q);
free(obj);
}
4.小结
通过学习队列线性表,对基本接口函数较为熟练掌握,而用队列实现栈,只是调用了队列的接口函数完成对应栈的操作。