如何只用队头指针实现顺序循环队列?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何只用队头指针实现顺序循环队列?相关的知识,希望对你有一定的参考价值。

【C的数据结构】如何只用队头指针实现顺序循环队列?
★要求有算法说明跟代码★
只用队头指针跟计数器哦

帅哥,代码就算了吧,很长的,你可以去书店找《数据结构》严蔚敏的教材
我可以给你说一下其算法思路:

一般的讲,一个顺序队列一定要设计成顺序循环队列的数据结构,否则就会出现“假溢出”的现象。

假溢出是指,这样的溢出并不是由于存储空间不够而造成的,而是由于队列的队尾指针不能自动由所定义的最大值自动转为最小值(即由队尾转向队头)

防止假溢出的方法就是用“顺序循环队列”

假设对头指针是front,队尾指针是rear
那么让队尾指针+1就自动指向对头——这就是循环
这是靠%运算实现的:
(rear+1)%N==front , 其中N是存储空间的大小

那么在顺序循环队列中,如何判断“队列满”和“队列空”这两种状态呢?
一般的做法是,少用一个存储空间。这样的话:
队列空的条件:rear==front
队列满的条件:(rear+1)%N==front

你所说的只用对头指针实现顺序循环队列,我个人认为这样的实现似乎不现实且无意义,你想想什么是队列ne?不就是队头出队尾进吗?你连队尾指针都没有,每次插入数据都要通过遍历算法来遍历整个队列,这样的效率真是....垃圾得可以,与其只用对头指针,还不如改用数组,你说呢??

还有,我看到你的补充了,你所说的计数器,其实质不就是队尾指针吗?对头指针永远指向对头,front+Count(Count是计数器值)不就是队尾指针的位置吗?所以计数器不就是换了种形式的队尾指针不是吗?
参考技术A 我最近做过一个只用尾指针的,其实两个性质差不多,只要把头尾连接起来就可以了。
#include <stdio.h>
#include <stdlib.h>

typedef int elemtype;
typedef struct node
elemtype data;
struct node *next;
qnode;
typedef struct
qnode *rear;
queue;

void create(queue *q);
void append(queue *q,int x);
void display(queue *q);
elemtype qdelete(queue *q);

int main()
queue *p;
int x,select;
printf("\n*****第一次操作请选择初始化并建立链队列!*****\n");
do
printf("\n 链队列的基本操作\n");
printf("==============================\n");
printf(" 主菜单 \n");
printf("==============================\n");
printf(" 1 初始化并建立链队列 \n");
printf(" 2 入链队列 \n");
printf(" 3 出链队列 \n");
printf(" 4 遍历链队列 \n");
printf(" 5 结束程序运行 \n");
printf("==============================\n");
scanf("%d",&select);
switch(select)
case 1:
p=(queue *)malloc(sizeof(queue));
create(p);
display(p);
break;
case 2:
printf("请输入队列元素的值:");
scanf("%d",&x);
append(p,x);
display(p);
break;
case 3:
printf("出链队列元素:x=%d",qdelete(p));
display(p);
break;
case 4:
display(p);
break;
case 5:
exit(0);


while(select>=1&&select<=5);
return 0;


void create(queue *q)
qnode *h;
int i,n,x;
printf("请输入将建立链队列元素的个数n:");
scanf("%d",&n);
h=(qnode *)malloc(sizeof(qnode));
h->next=NULL;
q->rear=h;
q->rear->next=h;
for(i=1;i<=n;i++)
printf("链队列第%d个元素的值为:",i);
scanf("%d",&x);
append(q,x);



void append(queue *q,int x)
qnode *s;
s=(qnode *)malloc(sizeof(qnode));
s->data=x;
s->next=q->rear->next;
q->rear->next=s;
q->rear=s;


void display(queue *q)
qnode *p;
p=q->rear->next->next;
printf("\n链队列元素依次为:");
while(p!=q->rear->next)
printf("%d-->",p->data);
p=p->next;

printf("\n\n遍历链队列结束!\n");


elemtype qdelete(queue *q)
qnode *p;
elemtype x;
if(q->rear->next==q->rear)
printf("队列为空!\n");
x=0;

else
p=q->rear->next->next;
q->rear->next->next=p->next;
if(p->next==NULL)
q->rear=q->rear->next;
x=p->data;
free(p);

return x;
参考技术B ................................................

Java 循环队列的实现

队列概念

  队列(Queue)是限定只能在一端插入、另一端删除的线性表。允许删除的一端叫做队头(front),允许插入的一端叫做队尾(rear),没有元素的队列称为“空队列”。

  队列具有先进先出(FIFO)的特性。

  普通顺序队列存在的问题

    在普通顺序队列中,入队的操作就是先将尾指针rear右移一个单位,然后将元素值赋值给rear单位。出队时,则是头指针front后移一个单位。像这样进行了一定数量的入队和出队操作后,可能会出现这样的情况:

    尾指针rear已指到数组的最后有一个元素,即rear==MaxLen-1,此时若再数组的前面部分可能还有很多闲置空间,即这种溢出并非是真的没有可用的存储空间,故称这种溢出现象为“假溢出”。显然,必须要解决这一块假溢出的问题,否则顺序队列就没有太多使用价值。

  循环队列

    循环队列的存储结构,头、尾指针都和普通顺序队列相同。不同的只是将队列视为“环状结构”,即data[0]为紧接着data[MaxLen-1]的单元,为相邻的元素,首位成为一个环。结构如下:(来自:百科)

 

代码实现

  全局变量:定义队列长度

  

static int MaxLen;

  循环队列基本数据结构的实现:

static class myQueue{
            int front;
            int rear;
            int queueList[];
            public myQueue() {
                // TODO Auto-generated constructor stub    
                queueList=new int[MaxLen];
                front=0;
                rear=0;
            }
}

  判空函数

public boolean isEmpty() {
                if(front==rear){
                return true;
            }
                return false;
            }

  判满函数

public boolean isFull(){
                if(((rear+1)%MaxLen)==front){
                    return true;
                }
                else{
                    return false;
                }
            }

 取队头元素

 

public void queueFront(int getFront){
                if(isEmpty()==false){
                    getFront=queueList[(front+1)%MaxLen];
                }
                else {
                    System.out.println("ERROR:Queue is Empty");
                    return;
                }
            }

入队

public void enQueue(int enData) {
                if(isFull()==false){
                    rear=(rear+1)%MaxLen;
                    this.queueList[rear]=enData;
                }
                else{
                    System.out.println("ERROR:Queue is Full");
                    return;
                }
                
            }

出队

public void outQueue() {
                if(isEmpty()==false){
                    front=(front+1)%MaxLen;
                }
                else {
                    System.out.println("ERROR:Queue is Empty");
                    return;
                }
                
            }

 

以上是关于如何只用队头指针实现顺序循环队列?的主要内容,如果未能解决你的问题,请参考以下文章

go语言循环队列的实现

循环队列

Java 循环队列的实现

循环队列

循环队列

用顺序表实现一个循环队列