顺序队列的入队操作

可以假想军训的时候理解
服务器君一共花费了224.470 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议
  • 昨天我们定义了顺序队列的ADT,还写了顺序队列的初始化函数。那么现在我们马上来看队列的一个重要的基础操作:入队。想想,入队的算法应该怎么写?
  • 额……想想。首先队列是线性表,用数组实现,所以首先要判断队列是不是满的。

如何判断一个队列是否满的?

假设我们在军训中排队,每个人报数。一个队列只能站10个人,从1报到10,队就满了。后来呢,队头的两个人出队了,然后又补充了两个新队员,那么这时候的报数是3到12。这时队列也是满的。

是不是有点思路了?没错,满足(12 + 1) mod 10 = 0就能说明队满了。所以条件就是 (Q->rear+1)%MAXSIZE == Q->front ,队头指针加1再mod队列长度,如果值为0,就说明队满。程序如下:

/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{
	if ((Q->rear+1)%MAXSIZE == Q->front)	/* 队列满的判断 */
		return ERROR;
	// to do ……
}
  • 嗯,如果队不满,我们就可以入队了。入队的思路就是,先给队尾元素赋值,然后再将队尾指针向后移动一位。比如从空队列开始,此时 Q->front == Q->rear,这个时候插入元素的话,其实就是给 data[Q->rear] 赋值 e,然后队尾指针 Q->rear 向后移动一位重新赋值。问题是如何赋值呢?

我们在定义队列的结构体的时候并没有一个单独的变量来记录队列的长度,比如前面谈到栈的时候,我们在定义结构体的时候,多定义了一个 int count; 来记录长度,这时移动指针也是很方便。

虽然我们在定义队列的时候没这个长度变量,但是我们可以通过模计算来取得我们需要的。将队尾指针向后移动一位?很简单,Q->rear = (Q->rear+1)%MAXSIZE; 即可。

所以入队函数设计成这样:

/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{
	if ((Q->rear+1)%MAXSIZE == Q->front)	/* 队列满的判断 */
		return ERROR;
	Q->data[Q->rear]=e;			/* 将元素e赋值给队尾 */
	Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
								/* 若到最后则转到数组头部 */
	return  OK;
}
  • 原来这么简单。我把遍历操作也补上吧,一会给个完整的程序。
#include "stdio.h"
#include "stdlib.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;
/* QElemType类型根据实际情况而定,这里假设为int */
typedef int QElemType;

/* 循环队列的顺序存储结构 */
typedef struct
{
	QElemType data[MAXSIZE];
	int front;    	/* 头指针 */
	int rear;		/* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
}SqQueue;

/* 初始化一个空队列Q */
Status InitQueue(SqQueue *Q)
{
	Q->front=0;
	Q->rear=0;
	return  OK;
}

Status visit(QElemType c)
{
	printf("%d ",c);
	return OK;
}

/* 从队头到队尾依次对队列Q中每个元素输出 */
Status QueueTraverse(SqQueue Q)
{
	int i;
	i=Q.front;
	while((i+Q.front)!=Q.rear)
	{
		visit(Q.data[i]);
		i=(i+1)%MAXSIZE;
	}
	printf("\n");
	return OK;
}

/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{
	if ((Q->rear+1)%MAXSIZE == Q->front)	/* 队列满的判断 */
		return ERROR;
	Q->data[Q->rear]=e;			/* 将元素e赋值给队尾 */
	Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
								/* 若到最后则转到数组头部 */
	return  OK;
}

int main()
{
    int opp, j;
    SqQueue Q;
    QElemType d;
    InitQueue(&Q);


    printf("\n1.给队列附初始值 \n2.遍历队列 \n3.入队 ");
    printf("\n0.退出 \n请选择你的操作:\n");
    while(opp != '0')
    {
        scanf("%d",&opp);
        switch(opp)
        {
            case 1:
                srand(time(0));
                for(j=1; j<=10; j++)
                {
                    d = rand()%100+1;
                    EnQueue(&Q,d);
                }
                QueueTraverse(Q);
                break;

            case 2:
                QueueTraverse(Q);
                break;

            case 3:
                printf("请输入需要入队的元素:");
                scanf("%d", &d);
                EnQueue(&Q,d);
                QueueTraverse(Q);
                break;

            case 0:
                exit(0);
        }
    }
    return 0;
}

延伸阅读

此文章所在专题列表如下:

  1. 栈的定义与大概理解
  2. 栈的抽象数据类型ADT
  3. 顺序栈:栈的顺序存储结构
  4. 顺序栈的进栈操作
  5. 顺序栈的出栈操作
  6. 获取顺序栈的栈顶元素
  7. 链栈:栈的链式存储结构
  8. 链栈的进栈操作
  9. 链栈的初始化与遍历
  10. 链栈的出栈操作
  11. 链栈的置空操作与判断链栈是否为空
  12. 为什么要使用栈这种数据结构
  13. 递归,栈的重要应用之一
  14. 栈是如何实现递归的
  15. 接触后缀表达式(逆波兰表示法)
  16. 图解后缀表达式的计算过程
  17. 将中缀表达式转化为后缀表达式
  18. 开始学习队列这个数据结构
  19. 队列的抽象数据类型ADT
  20. 顺序队列:队列的顺序存储结构
  21. 顺序队列的入队操作
  22. 顺序队列的出队操作
  23. 顺序队列置空与判断操作
  24. 队列顺序存储结构的不足
  25. 关于循环队列的一些讲解
  26. 链队列:队列的链式存储结构
  27. 链队列的初始化操作
  28. 链队列的入队操作
  29. 链队列的出队操作
  30. 补完链队列的其它常见操作
  31. 循环队列与链队列的优劣势

本文地址:http://www.nowamagic.net/librarys/veda/detail/2344,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/2344

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《致加西亚的信》 阿尔伯特·哈伯德(Hubbard.E.) (作者), 赵立光 (译者), 艾柯 (译者)

《致加西亚的信(经典盒装版)》内容简介:美西战争爆发以后,美国必须立即与古巴起义军首领加西亚取得联系,并获得他的合作。但当时,加西亚身在古巴的深山里——没有人知道他的确切地点,所以没法与他取得联系。这时,有人向总统推荐一个名叫罗文的人,说他有办法找到加西亚,而且也只有他才能找得到。他们找来罗文,交给他一封写给加西亚的信。三周后,罗文徒步走过一个危机四伏的国家,最终把那封信交给了加西亚。 此后,罗文的事迹被传为佳话,“送信”成为了敬业、忠诚、勤奋的象征,罗文便成了每个领导都想找到的人和每个员工都应该学习和效仿的榜样。

更多计算机宝库...