队列的学习

定义

队列(queue)是只允许在一端进行插入,在另一端进行删除的运算受限的线性表。
  1. 允许插入的一端叫做队尾(rear)
  2. 允许删除的一端叫做队头(front)
  3. 当队列中没有元素时叫做空队列
  4. 队列是一种先进先出的线性表,也称为FIFO表

顺序队列

顺序队列的定义

队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表

顺序队列的表示

  1. 顺序队列用一个向量空间来存放当前的队列中的元素
  2. 由于队列中队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的位置在队列初始化时均应置为0

顺序队列的基本操作

  1. 入队时:将新元素插入rear所指的位置,并将rear+1
  2. 出队时:删除front所指的元素,并将front+1
注意:
  1. 当头尾指针相等时,队列为空
  2. 在非空队列里,队头指针始终指向队头元素,队尾指针始终指向队尾元素的下一个位置

顺序队列中的溢出现象

  1. 下溢:队列为空时,做出队操作产生的溢出现象
  2. 真上溢:当队列满时,做入队操作产生的空间溢出现象。
  3. 假上溢:由于入队和出队操作中,队头指针只增加不减少,致使被删除的元素空间永远无法重新利用,从而导致入队操作时产生假上溢现象。

循环队列

为了充分利用初始分配的向量空间,克服“假上溢”的方法是:将向量空间想像成一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(circular queue).

循环队列的基本操作

当循环队列进行入队和出队操作时,队头和队尾指针仍要+1。只不过当头指针指向向量上界(queuesize - 1)时,其+1操作是指向向量空间的下界0.这种循环意义下的+1操作用代码描述为
  1. if(front == queuesize - 1)
    {
    	front = 0;
    }else
    {
    	front ++;
    }

  2. front = (front + 1) % queuesize;


循环队列边界处理的方法

  1. 另设一个布尔变量来区分队列的空和满。
  2. 设一个计数器记录当前队列中的元素

循环队列的类型定义

#define queuesize 100001	//最大队列长度
#define type int	//队列中存储的元素类型

struct queue
{
	int front;
	int rear;
	type data[queuesize];
	int count;	//记录队列中的元素
};

循环队列的基本操作
/**
 * Description:队列初始化
 */
void InitQueue(struct queue *Q)
{
	Q -> front = Q -> rear = 0;
	Q -> count = 0;
}

/**
 * Description:队列判空
 */
int QueueEmpty(struct queue *Q)
{
	int flag;

	flag = (Q -> count == 0)? 1 : 0;

	return flag;
}

/**
 * Description:队列判满
 */
int QueueFull(struct queue *Q)
{
	int flag;

	flag = (Q -> count == queuesize)? 1 : 0;

	return flag;
}

/**
 * Description:入队操作
 */
void EnQueue(struct queue *Q, type element)
{
	int flag;

	flag = QueueFull(Q);
	if(!flag)
	{
		Q -> data[Q -> rear] = element;
		Q -> count ++;
		Q -> rear = (Q -> rear + 1) % queuesize;
	}else
	{
		printf("failed\n");
	}
}

/**
 * Description:出队操作
 */
void Dequeue(struct queue *Q)
{
	int flag;
	type element;

	flag = QueueEmpty(Q);

	if(!flag)
	{
		element = Q -> data[Q -> front];
		Q -> front = (Q -> front + 1) % queuesize;
		Q -> count --;
	}else
	{
		printf("failed\n");
	}
}

/**
 * Description:查找队列中的指定元素
 */
void QueueSearch(struct queue *Q, int k)
{
	if(!QueueEmpty(Q) && 1 <= k <= queuesize)
	{
		printf("%d\n",Q -> data[k - 1]);
	}else
	{
		printf("failed\n");
	}
}


链队列

定义

队列的链式存储结构简称链队列。它是限制在表头进行删除,在表尾进行插入的单链表。

类型定义

struct qnode
{
	int data;
	struct qnode *next;
};

struct linkqueue
{
	struct qnode *front;
	struct qnode *rear;
};

操作集合

/**
 * Description:构造链队列
 */
void InitQueue(struct linkqueue *Q)
{
	Q -> front = Q -> rear = NULL;
}

/**
 * Description:判队空
 */
int QueueEmpty(struct linkqueue *Q)
{
	int flag;

	flag = (Q -> front == NULL && Q -> rear == NULL)? 1 : 0;

	return flag;
}

/**
 * Description:入队
 */
void EnQueue(struct linkqueue *Q, int data)
{
	struct qnode *s;
	s = malloc(sizeof(struct qnode));
	s -> data = data;
	s -> next = NULL;
	if(QueueEmpty(Q))
	{
		//将x插入空队列
		Q -> front = Q -> rear = s;
	}else
	{
		//将x插入非空队列
		Q -> rear -> next = s;
		Q -> rear = s;
	}
}

/**
 * Description:出队
 */
void DeQueue(struct linkqueue *Q)
{
	struct qnode *p;
	if(QueueEmpty)
	{
		printf("队为空\n");
	}else
	{
		p = Q -> front;
		Q -> front = Q -> front -> next;
		if(p == Q -> rear)
		{
			//队里只有一个节点,删去后需要将尾节点置空
			Q -> rear = NULL;
		}
		free(p);
	}
}




你可能感兴趣的:(队列的学习)