C语言数据结构队列
C语言数据结构队列
队列也有顺序储存与链式储存(此处我以顺序为例)
队列:类似于排队,一般是队尾入队,队头出队。
队列的一般形式
一种是:利用数组分配一段连续的内存空间。
另一种是:动态分配一个连续的内存空间。
首先定义一个队列的结构体类型:
typedef struct SqQueue//定义一个顺序队列的结构体类型
{
int *base;//用于记录存储空间的基地址
int front;//“头指针”
int rear;//"尾指针"
}SqQueue;
初始化:
void InitQueue(SqQueue *Q)
{
Q->base=(int *)malloc(sizeof(int)*MAX);//由结构体指针接受并返回这段连续的内存空间的基地址
if(Q->base==NULL)
{
printf("分配空间失败!\n");
exit(1);
}
Q->front=Q->rear=0;//初始化时将“头指针”和“尾指针”都指向这段连续空间的首地址
return;
}
对于此类队列:
- 队列需要一个头指针与一个尾指针 头指针:front
- 初始化队列
- 尾指针:rear
分配一段连续的内存空间
- 入队与出队
- 将front=rear=0
入队:rear++,front不动
- 出队:front++,rear不动
但是:
这样就会出现”假溢出“的情况(即队尾指针移动到底但是队头出队又留下了新的空间)
所以这里我们引入一个新的概念“循环队列”
即再队尾指针指向连续空间末尾时,下一次会重新回到这个连续空间的首地址。 这样便有效的避免了假溢出的现象 而新的问题又出现了
- 使用了这一个循环队列如何描述队尾与队头指针的移动?
- 如何解决Q.rear==Q.front在循环队列中的二义性?
- 如何求取循环队列的长度问题?
以下个人见解:
这里引入:
- 模运算即以Q.rear=(Q.rear+1)%Max与Q.front=(Q.front+1)%Max来描述指针的移动。
- 重新设置队满条件即(Q.rear+1)%Max==Q.front时表示队满此时其实队列仍有一个空位置。
- 求队的长度
如其值等于Max-1时+1%Max将会重回0号位置,而在此之前均表示向后移动一位(Max表示队列最大长度)
但是为了保证Q.rear==Q.front是表示队空的情况,即是由出队Q.front=(Q.front+1)%Max追上Q.rear时的情况。
再循环队列中会出现两种情况: a.此类情况是当队尾指针与队头指针都没有进入相对于对方的下一次循环中即
- Q.rear-Q.front的值为正的情况下此时队长就是两者的差值
- b.而另一类情况则是在Q.rear进入下一次循环时Q.front还未进入下一次循环即
- Q.rear-Q.front的值为负的情况下此时队长是(Q.rear-Q.front+Max)
- 此处个人理解解释:此时队长应为(Q.front-Q.rear)相对于Max的"补集"的长度!!!!!!
- 而为了统一a类与b类的形式此处使用"(Q.rear-Q.front+Max)%Max"
- 这样既不会对a产生影响,且直接在()内部直接完成了对b类补集的计算。
参考代码: