赞
踩
typedef struct{
ElemType data[MaxSize]; //静态数组存放队列元素
int front; //队头指针
int rear; //队尾指针
}SqQueue;
初始化
void InitQueue(SqQueue &Q){
Q.rear=Q.front=0;
}
判空
bool QueueEmpty(SqQueue &Q){
if(Q.rear==Q.front)
return true;
else
return false;
}
假溢出问题
当rear走到队尾,队头出栈后仍然有存储空间。
所以,根据
rear==MaxSize
判溢出会导致存储空间的浪费。
用循环队列解决假溢出问题:
把队列看成一个环,rear走到最后一个存储空间时,会重新回到第一个存储空间重新判断。
- 用取模运算实现环。
队满实现
- 注:不能以
rear==front
来判断队满,因为已经用rear==front
这个条件判断空队列,所以判满必须牺牲一个存储单元。
另外一些操作
- 队首指针进1:
Q.front=(Q.front+1)%MaxSize
- 队尾指针进1:
Q.rear=(Q.rear+1)%MaxSize
- 队列长度:
(Q.rear+MaxSize-Q.front)%MaxSize
若要求不能浪费那一块存储空间:
方法一:设置size变量记录队中的元素个数:
typedef struct{ ElemType data[MaxSize]; int front,rear; int size; //队列当前长度 }SqQueue; //初始化时 rear=front=0; size=0; //队满条件 size=MaxSize; //队空条件 size=0;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
方法二:设置tag记录最新一次的操作是删除还是插入
typedef struct{ ElemType data[MaxSize]; int front,rear; int tag; //最近进行的是删除/插入操作 }SqQueue; //tag的定义: //插入操作成功时:tag=1; //删除操作成功时:tag=0。 //只有删除操作,才可能导致队空 //只有插入操作,才可能导致队满 //初始化 rear=front=0; tag=0; //队空条件 front==rear&&tag==0 //队满条件 front==rear&&tag==1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
bool EnQueue(SqQueue &Q,ElemType x){
if((Q.rear+1)%MaxSize==Q.front)return false; //队列已满
Q.data[Q.rear]=x; //新元素插入
Q.rear=(Q.rear+1)%MaxSize; //队尾加一取模
return true;
}
bool DeQueue(SqQueue &Q,ElemType &x){
if(Q.rear==Q.front)return false; //队空报错
x=Q.data[Q.front]; //返回出队元素
Q.front=(Q.front+1)%MaxSize; //队头指针后移
return true;
}
bool GetHead(SqQueue Q,ElemType &x){
if(Q.rear==Q.front)return false;
x=Q.data[Q.front];
return true;
}
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #define ElemType int #define MaxSize 5 typedef struct { ElemType data[MaxSize]; int front, rear; }SqQueue; void InitQueue(SqQueue& Q) { Q.front = Q.rear = 0; } bool QueueEmpty(SqQueue& Q) { if (Q.rear == Q.front) return true; else return false; } int Length(SqQueue& Q) { return (Q.rear + MaxSize - Q.front) % MaxSize; } bool EnQueue(SqQueue& Q, ElemType x) { if ((Q.rear + 1) % MaxSize == Q.front)return false; Q.data[Q.rear] = x; Q.rear = (Q.rear + 1) % MaxSize; return true; } bool DeQueue(SqQueue& Q,ElemType &x) { if (Q.rear == Q.front)return false; x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; return true; } bool GetHead(SqQueue Q, ElemType& x) { if (Q.rear == Q.front)return false; x = Q.data[Q.front]; return true; } //从队头开始打印 void PrintQ(SqQueue Q) { int p = Q.front; while (p!=Q.rear) { printf("%d ", Q.data[p]); p = (p +1) % MaxSize; } printf("\n\n"); } int main(){ SqQueue Q; InitQueue(Q); printf("入栈:\n"); EnQueue(Q, 1); EnQueue(Q, 2); EnQueue(Q, 3); EnQueue(Q, 4); PrintQ(Q); printf("队列长度:%d\n", Length(Q)); printf("出栈:\n"); int x; DeQueue(Q, x); printf("出栈元素为:%d\n", x); DeQueue(Q, x); printf("出栈元素为:%d\n", x); PrintQ(Q); GetHead(Q, x); printf("栈顶元素:%d\n", x); printf("循环队列测试:\n"); EnQueue(Q, 5); EnQueue(Q, 6); EnQueue(Q, 7); PrintQ(Q); DeQueue(Q, x); PrintQ(Q); }
就是一个有队头指针和队尾指针的单链表。
//链式队列结点
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}LinkNode;
//链式队列
typedef struct{
LinkNode *front,*rear;
}LinkQueue;
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #define ElemType int typedef struct LinkNode{ ElemType data; struct LinkNode* next; }LinkNode; typedef struct { LinkNode* front, * rear; }LinkQueue; void InitQueue(LinkQueue& Q) { Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode)); Q.front->next = Q.rear->next = NULL; } bool isEmpty(LinkQueue& Q) { if (Q.front == Q.rear) return true; else return false; } void EnQueue(LinkQueue& Q, ElemType x) { LinkNode* p = (LinkNode*)malloc(sizeof(LinkNode)); p->data = x; p->next = NULL; Q.rear->next = p; Q.rear = p; } bool DeQueue(LinkQueue& Q, ElemType& x) { if (Q.front == Q.rear)return false; //空栈 LinkNode* p = Q.front->next; x = p->data; Q.front->next = p->next; if (Q.rear == p)Q.rear = Q.front; //若原队列中只有一个结点,则删除后变空 free(p); return true; } void PrintQ(LinkQueue& Q) { LinkNode* p = Q.front->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n\n"); } int main() { LinkQueue Q; InitQueue(Q); printf("入栈:\n"); EnQueue(Q, 1); EnQueue(Q, 2); EnQueue(Q, 3); EnQueue(Q, 4); PrintQ(Q); printf("出栈:\n"); int x; DeQueue(Q, x); printf("出栈元素为:%d\n", x); DeQueue(Q, x); printf("出栈元素为:%d\n", x); PrintQ(Q); }
定义
也是插入和删除受限的线性表:
还有输入受限或输出受限的双端队列:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。