对于队列来说,从队尾进,队尾出,要设置一个结点类型的指针q->front,和q->rear,q->front指向的结点是一个特殊的结点,不存放值,next指针域指向的是第一个有效的结点,实际上就是队首结点,而q->rear开始时与q->front相同,随着不断的入列,永远指向最后一个有效结点,q->rear->next为NULL,其它结点的next域不为NULL。
LinkNode p = (LinkNode)malloc(sizeof(NODE));
之所以要对指针类型的p进行malloc是因为仅有指针实际上没有在内存中开辟空间,所以要用malloc为指针指向的结点进行实际内存的分配,而如果是NODE进行定义则不需分配在定义时就完成了分配。在删除结点时,要进行free并且防止野指针:
free(p);
p = NULL;
向下面演示简单的代码,有队列的初始化,判断队列是否为空,入队和出队的操作:
#include
#include
#include
typedef struct Node {
int val;
Node *next;
}NODE, *LinkNode;
typedef struct QNode {
LinkNode front, rear;
}Queue, *LinkQueue;
void InitQueue(LinkQueue queue)
{
queue->front = queue->rear = (LinkNode)malloc(sizeof(NODE));
if (!queue->front)
printf("error!\n");
queue->front->next = NULL;
}
bool IsEmpty(LinkQueue queue)
{
if (queue->front == queue->rear)
return true;
else
return false;
}
void EnQueue(LinkQueue queue, int value)
{
LinkNode p = (LinkNode)malloc(sizeof(NODE));
if (!p)
printf("error!\n");
p->val = value;
p->next = NULL;
queue->rear->next = p;
queue->rear = p;
}
//头结点next域指向第一个有效结点
void DeQueue(LinkQueue queue)
{
if (IsEmpty(queue))
{
printf("error!队列为空");
}
LinkNode p = queue->front->next;
queue->front->next = p->next;
if (queue->rear == p)
queue->front = queue->rear; //当只有一个结点时,p->next为NULL
free(p);
p = NULL;
}
void Traverse(LinkQueue queue)
{
if (IsEmpty(queue))
{
printf("error!队列为空");
exit(0);
}
printf("遍历队列的结果是: ");
LinkNode p = queue->front->next;
while (p != NULL)
{
printf("%d ", p->val);
p = p->next;
}
printf("\n");
}
int main()
{
Queue queue;
InitQueue(&queue);
EnQueue(&queue, 1);
EnQueue(&queue, 2);
EnQueue(&queue, 3);
Traverse(&queue);
DeQueue(&queue);
Traverse(&queue);
DeQueue(&queue);
DeQueue(&queue);
if (IsEmpty(&queue))
printf("此时栈为空\n");
return 0;
}
输出结果为:
2. 再来介绍一下循环队列,这里的循环队列要有一个front,rear指针,当然这里的指针是名义上的,由于这里的循环队列使用的是顺序结构,就是开辟了一个数组,而不是上面那种链表,所以指针可以用数组下标int类型来表示,要注意的是,初始化循环链表时,q.front 和q.rear = 0相等,但q.front只随着出队前进,q.rear则随着入队前进,q.rear指向的是填有实际元素的结点的下一位,即开辟的MaxSize数组有一个单位不能使用,判断队满的方法就是q.rear的下一位就是q.front,此时q.rear指向的是没有存值的结点,代码为:
有一个问题时在函数定义时,参数只能用(SqQueue &queue)省去&会报错,这里暂时有点不够理解:
#include
#include
#include
#define MaxSize 4 //多一个单元方便判断队满
typedef struct {
int Block[4];
int front, rear;
}SqQueue;
void InitQueue(SqQueue &queue)
{
queue.front = queue.rear = 0;
}
bool IsEmpty(SqQueue &queue)
{
if (queue.front == queue.rear)
return true;
else
return false;
}
bool IsFull(SqQueue &queue)
{
if ((queue.rear + 1) % MaxSize == queue.front)
return true;
else
return false;
}
void EnQueue(SqQueue &queue, int value)
{
if (IsFull(queue))
{
printf("队满!\n");
}
else
{
queue.Block[queue.rear] = value;
queue.rear = (queue.rear + 1) % MaxSize;
}
}
//头结点next域指向第一个有效结点
void DeQueue(SqQueue &queue)
{
if (IsEmpty(queue))
{
printf("error!队列为空");
}
queue.front = (queue.front + 1) % MaxSize;
}
void Traverse(SqQueue &queue)
{
if (IsEmpty(queue))
{
printf("error!队列为空");
exit(0);
}
printf("遍历队列的结果是: ");
int p = queue.front;
while (p != queue.rear)
{
printf("%d ", queue.Block[p]);
p = (p + 1) % MaxSize;
}
printf("\n");
}
int main()
{
SqQueue queue;
InitQueue(queue);
EnQueue(queue, 1);
EnQueue(queue, 2);
EnQueue(queue, 3);
if (IsFull(queue))
printf("队满!\n");
Traverse(queue);
DeQueue(queue);
Traverse(queue);
EnQueue(queue, 1);
Traverse(queue);
DeQueue(queue);
Traverse(queue);
DeQueue(queue);
DeQueue(queue);
if (IsEmpty(queue))
printf("此时队为空\n");
return 0;
}
运行结果: