队列的基本操作!

浅浅的花香味﹌ 2022-04-11 08:08 410阅读 0赞

1.链式队列

//队列结点结构体

typedef struct QNode

{ QElemType data;

QNode *next;

}*Queueptr;

-——————————————-

//指向结点的指针

struct LinkQueue

{ Queueptr front,rear;

}

[cpp] view plain copy print ?

  1. void InitQueue(LinkQueue &Q)
  2. { // 构造一个空队列Q
  3. if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))
  4. exit(OVERFLOW);
  5. Q.front->next=NULL;
  6. }

  7. void DestroyQueue(LinkQueue &Q)
  8. { // 销毁队列Q(无论空否均可)
  9. while(Q.front)
  10. {
  11. Q.rear=Q.front->next;
  12. free(Q.front);
  13. Q.front=Q.rear;//释放一块内存要做两点:1.释放指向它的指针。2.将该指针指向空
  14. }
  15. }

  16. void ClearQueue(LinkQueue &Q)
  17. { // 将Q清为空队列
  18. QueuePtr p,q;
  19. Q.rear=Q.front;
  20. p=Q.front->next;
  21. Q.front->next=NULL;//只留下头结点
  22. while(p)
  23. {
  24. q=p;
  25. p=p->next;
  26. free(q);
  27. }
  28. }

  29. Status QueueEmpty(LinkQueue Q)
  30. { // 若Q为空队列,则返回TRUE,否则返回FALSE
  31. if(Q.front->next==NULL)//注意不要把链式队列的判空条件与循环队列混淆
  32. return TRUE;
  33. else
  34. return FALSE;
  35. }

  36. int QueueLength(LinkQueue Q)
  37. { // 求队列的长度
  38. int i=0;
  39. QueuePtr p;
  40. p=Q.front;
  41. while(Q.rear!=p)
  42. {
  43. i++;
  44. p=p->next;
  45. }
  46. return i;
  47. }

  48. Status GetHead(LinkQueue Q,QElemType &e)
  49. { // 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
  50. QueuePtr p;
  51. if(Q.front==Q.rear)
  52. return ERROR;
  53. p=Q.front->next;
  54. e=p->data;
  55. return OK;
  56. }

  57. void EnQueue(LinkQueue &Q,QElemType e)
  58. { // 插入元素e为Q的新的队尾元素
  59. QueuePtr p;
  60. if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存储分配失败
  61. exit(OVERFLOW);
  62. p->data=e;
  63. p->next=NULL;
  64. Q.rear->next=p;
  65. Q.rear=p;
  66. }

  67. Status DeQueue(LinkQueue &Q,QElemType &e)
  68. { // 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
  69. QueuePtr p;
  70. if(Q.front==Q.rear)
  71. return ERROR;
  72. p=Q.front->next;
  73. e=p->data;
  74. Q.front->next=p->next;
  75. if(Q.rear==p)
  76. Q.rear=Q.front;//如果只有一个节点,那么删除这个节点后rear指针也就丢了,需重新赋值
  77. free(p);
  78. return OK;
  79. }

  80. void QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
  81. { // 从队头到队尾依次对队列Q中每个元素调用函数vi()
  82. QueuePtr p;
  83. p=Q.front->next;
  84. while(p)
  85. {
  86. vi(p->data);
  87. p=p->next;
  88. }
  89. printf(“\n”);
  90. }</STRONG>

    void InitQueue(LinkQueue &Q) { // 构造一个空队列Q if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)))) exit(OVERFLOW); Q.front->next=NULL; } void DestroyQueue(LinkQueue &Q) { // 销毁队列Q(无论空否均可) while(Q.front) { Q.rear=Q.front->next; free(Q.front); Q.front=Q.rear;//释放一块内存要做两点:1.释放指向它的指针。2.将该指针指向空 } } void ClearQueue(LinkQueue &Q) { // 将Q清为空队列 QueuePtr p,q; Q.rear=Q.front; p=Q.front->next; Q.front->next=NULL;//只留下头结点 while(p) { q=p; p=p->next; free(q); } } Status QueueEmpty(LinkQueue Q) { // 若Q为空队列,则返回TRUE,否则返回FALSE if(Q.front->next==NULL)//注意不要把链式队列的判空条件与循环队列混淆 return TRUE; else return FALSE; } int QueueLength(LinkQueue Q) { // 求队列的长度 int i=0; QueuePtr p; p=Q.front; while(Q.rear!=p) { i++; p=p->next; } return i; } Status GetHead(LinkQueue Q,QElemType &e) { // 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; return OK; } void EnQueue(LinkQueue &Q,QElemType e) { // 插入元素e为Q的新的队尾元素 QueuePtr p; if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存储分配失败 exit(OVERFLOW); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; } Status DeQueue(LinkQueue &Q,QElemType &e) { // 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front;//如果只有一个节点,那么删除这个节点后rear指针也就丢了,需重新赋值 free(p); return OK; } void QueueTraverse(LinkQueue Q,void(*vi)(QElemType)) { // 从队头到队尾依次对队列Q中每个元素调用函数vi() QueuePtr p; p=Q.front->next; while(p) { vi(p->data); p=p->next; } printf(“\n”); }

2.顺序队列—-循环队列

性质如下:

1.头指针指向对头元素,尾指针指向队尾的下一个位置。(这里的指针都是为指针,实际是数组序号)

2.为了区分队满与对空,则定义一个存储空间为MAX_QSIZE大小的队列只允许存放MAX_QSIZE-1个数据。

3.判空条件为:if(Q.front ==Q.rear) return true;

判满条件为:if((Q.rear+1)%MAX_QSIZE==Q.front) return true;

4.循环队列的长度为:(Q.read-Q.front+MAX_SIZE)%MAX_QSIZE

5.当删除对头元素或者在对尾插入元素时指针均需向后移动。操作为:

Q.rear=(Q.rear+1)%MAX_QSIZE;

Q.front=(Q.front+1)%MAX_QSIZE;

结构体定义如下:

struct SqQueue

{QElemType *base;//指向开辟的空间的首地址

int front;

int rear;

}

[cpp] view plain copy print ?

  1. void InitQueue(SqQueue &Q)
  2. { // 构造一个空队列Q
  3. Q.base=(QElemType *)malloc(MAX_QSIZE*sizeof(QElemType));
  4. if(!Q.base) // 存储分配失败
  5. exit(OVERFLOW);
  6. Q.front=Q.rear=0;
  7. }

  8. void DestroyQueue(SqQueue &Q)
  9. { // 销毁队列Q,Q不再存在
  10. if(Q.base)
  11. free(Q.base);
  12. Q.base=NULL;
  13. Q.front=Q.rear=0;
  14. }

  15. void ClearQueue(SqQueue &Q)
  16. { // 将Q清为空队列
  17. Q.front=Q.rear=0;
  18. }

  19. Status QueueEmpty(SqQueue Q)
  20. { // 若队列Q为空队列,则返回TRUE;否则返回FALSE
  21. if(Q.front==Q.rear) // 队列空的标志
  22. return TRUE;
  23. else
  24. return FALSE;
  25. }

  26. int QueueLength(SqQueue Q)
  27. { // 返回Q的元素个数,即队列的长度
  28. return(Q.rear-Q.front+MAX_QSIZE)%MAX_QSIZE;
  29. }

  30. Status GetHead(SqQueue Q,QElemType &e)
  31. { // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
  32. if(Q.front==Q.rear) // 队列空
  33. return ERROR;
  34. e=Q.base[Q.front];//等价于e=*(Q.base+Q.front)
  35. return OK;
  36. }

  37. Status EnQueue(SqQueue &Q,QElemType e)
  38. { // 插入元素e为Q的新的队尾元素
  39. if((Q.rear+1)%MAX_QSIZE==Q.front) // 队列满
  40. return ERROR;
  41. Q.base[Q.rear]=e;//等价于*(Q.base+Q.rear)=e
  42. Q.rear=(Q.rear+1)%MAX_QSIZE;
  43. return OK;
  44. }

  45. Status DeQueue(SqQueue &Q,QElemType &e)
  46. { // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
  47. if(Q.front==Q.rear) // 队列空
  48. return ERROR;
  49. e=Q.base[Q.front];
  50. Q.front=(Q.front+1)%MAX_QSIZE;
  51. return OK;
  52. }

  53. void QueueTraverse(SqQueue Q,void(*vi)(QElemType))
  54. { // 从队头到队尾依次对队列Q中每个元素调用函数vi()
  55. int i;
  56. i=Q.front;
  57. while(i!=Q.rear)
  58. {
  59. vi(Q.base[i]);
  60. i=(i+1)%MAX_QSIZE;
  61. }
  62. printf(“\n”);
  63. }

发表评论

表情:
评论列表 (有 0 条评论,410人围观)

还没有评论,来说两句吧...

相关阅读

    相关 基本操作

    目录 一、什么是队列? 二、用数组实现队列 代码实现: 数组实现的缺点: 三、用链表实现队列 代码实现: -------------------- 一、什么

    相关 循环基本操作

    循环队列设置不同队空与队满条件的解决方案 为了解决顺序队列假溢出的问题,我们采用的方案是少用一个元素空间,此时的指针状态是队尾指针加1才与队头指针重合,于是此时队满的判定