基本数据结构之队列

一、基本数据结构之队列

       队列作为计算机系统一种非常常见的数据结构被大家所熟知。同堆栈一样,队列也是有插入和删除只能在限定段的线性表。

         队列是一种FIFO(First In First Out)的线性表。具体通常用链表或数组来实现。队列只允许在后端(rear)进行插入操作,在前段(front)进行删除操作。

         队列的操作方式和堆栈类似,唯一的区别就是队列只允许在后端进行数据添加。

         队列通常能够解决一下问题:

         1)解决主机与外部设备之间速度不匹配的问题。设置一个缓冲队列。

         2)解决因多用户引起的资源竞争问题。系统按照请求时间设置一个请求队列(还可以给每个任务加一个优先级,就成为了优先级队列)。

         下面介绍队列的几种常见的实现方式:

        

/*
单链队列的实现:单链队列使用链表作为基本数据结构,所以不存在溢出问题(除非主存耗完),队列长度也没有限制。
但是插入和读取的时间成本较高。
*/
/* 单链队列--队列的链式存储结构 */
typedef struct QNode {
  QElemType data;
  struct QNode *next;
}QNode, *QueuePtr;

typedef struc {
  QueuePtr front, rear; /* 队头队尾指针 */
}LinkQueue;

/* 链队列的基本操作(9个) */

/* 构造一个空队列 */
void InitQueue(LinkQueue *Q)
{
  Q->font = Q->rear = malloc(sizeof(QNode);
  if(!Q->font)
    exit(1);
  Q->front->next = NULL;
}

/* 销毁队列Q */
void DestroyQueue(LinkQueue *Q)
{
  while(Q->front) {
    Q->rear = Q->front->next;
    free(Q->front);
    Q->front = Q->rear;
  }
}

/* 清空队列Q */
void ClearQueue(LinkQueue *Q)
{
  QueuePtr p,q;
  Q->rear = Q->front;
  p = Q->front->next;
  Q->front->next = NULL;
  while(p) {
    q = p;
    p = q->next;
    free(q);
  }
}

/* 若Q为空队列,则返回TRUE,否则返回FALSE */
Status QueueEmpty(LinkQueue Q)
{
  if(Q->font->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;
}

/* 若队列不为空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */
Status GetHead_Q(LinkQueue Q, QElemType *e)
{
  QueuePtr p;
  if(Q.front == Q.rear)
    return ERROR;
  p = Q.front->next;
  *e = p->data;
  return OK;
}

/* 插入e作为Q新的队尾元素 */
void EnQueue(LinkQueue *Q, QElemType e)
{
  QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
  if(!p)
    exit(1);
  p->data = e;
  p->next = NULL;
  Q->rear->next = p;
  Q->rear = p;
}

/* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
Status DeQueue(LinkQueue *Q, QElemType *e)
{
  QueuePtr p;
  if(Q->front == Q->rear)
    return ERROR;
  p = Q->front; /* 指向头结点 */
  *e = p->data;
  Q->front = p->next;
  if(Q->rear == p)
    Q->rear = Q->front;
  free(p);
  return OK;
}

/* 从队头到队尾依次对队列Q中每个元素调用函数vi() */
void QueueTraverse(LinkQueue Q, (void)(*visit)(QElemType))
{
  QueuePtr p;
  p = Q.front->next;
  while(p) {
    visit(p->data);
    p = p->next;
  }
  printf("\n");
}
-----------------------------我就是分割线啦---------------------------
循环队列
循环队列可以更简单防止伪溢出的发生,但队列大小是固定的。
/* 队列的顺序存储结构(循环队列) */
#define MAX_QSIZE 5 /* 最大队列长度加1*/
typedef struct {
  QElemType *base;/* 初始化的动态分配存储空间 */
  int front;/* 头指针,若队列不空,指向队列头元素 */
  int rear;/* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
}SqQueue;

循环队列的基本操作(9个)
/* 构造一个空队列 */
void InitQueue(SqQueue *Q)
{
  Q->base = malloc(MAX_QSIZE * sizeof(QElemType));
  if(!Q->base)
    exit(1);
  Q->front = Q->rear = 0;
}

/* 销毁队列Q,Q不再存在 */
void DestroyQueue(SqQueue *Q)
{
  if(Q->base)
    free(Q->base);
  Q->base = NULL;
  Q->front = Q->rear = 0;
}

/* 将Q清为空队列 */
void ClearQueue(SeQueue *Q)
{
  Q->front = Q->rear = 0;
}

/* 若队列Q为空队列,则返回TRUE;否则返回FALSE */
Status QueueEmpty(SqQueue Q)
{
  if(Q.front == Q.rear)
    return TRUE:
  else
    return FALSE:
}

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

/* 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR */
Status GetHead(SqQueue Q, QElemType *e)
{
  if(Q.front == Q.rear)
    return ERROR; // 队列为空
  *e = Q.base[Q.front];
  return OK;
}

/* 插入元素e为Q的新的队尾元素 */
Status EnQueue (SeQueue *Q, QElemType *e)
{
  if((Q->rear+1)% MAX_QSIZE == Q->front) // 队列满
    return ERROR;
  Q->base[Q->rear] = e;
  Q->rear = (Q->rear + 1) % MAX_QSIZE;
  return OK;
}

/* 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR */
Status DeQueue(SqQueue *Q, ElemType *e)
{
  if(Q->front == Q->rear) // 队列空
    return ERROR;
  *e = Q->base[Q->front];
  Q->front = (Q->front+1) % MAX_QSIZE;
  return OK;
}

/* 从队头到队尾依次对队列Q中每个元素调用函数visit() */
void QueueTraverse(SqQueue Q, void(*visit)(QElemType))
{
  int i ;
  i = Q.front;
  while(i!=Q.rear)
  {
    visit(Q.base[i];
    i = (i+1)%MAX_QSIZE;
  }
  printf("\n");
}
---------------------------------------------我还是分割线---------------------
#include<stdio.h>
#include<stdlib.h>
/*阵列结构,说白了就是用数组存储元素 */
struct Queue
{
  int Array[10];//阵列空间大小
  int head;//前端(front)
  int tail;//后端(rear)
  int length;//当前队列长度,并且使用此成员判断满和空
};

/*元素插入队列*/
void EnQueue(struct Queue *Queue1,int x)
{
  Queue1->Array[Queue1->tail]=x;
  if(Queue1->tail+1==10)//Queue1->length 改空间大小为10
  {
    Queue1->tail=0;//1改为0
  }
  else
  {
    Queue1->tail=Queue1->tail+1;
  }
  Queue1->length=Queue1->length+1;//当前个数增1
}

/*删除队列元素*/
int DeQueue(struct Queue *Queue1)
{
  int x=Queue1->Array[Queue1->head];
  if(Queue1->head+1==10)//空間大小10
  {
    Queue1->head=0;
  }
  else
  {
    Queue1->head=Queue1->head+1;
  }
  Queue1->length=Queue1->length-1;//移出后減少1
  return x;
}
/*基本操作*/
int main()
{
  struct Queue *Queue1=malloc(sizeof(struct Queue));
  Queue1->length=0;
  Queue1->head=0;
  Queue1->tail=0;
  EnQueue(Queue1,5);//將5放入
  EnQueue(Queue1,8);//將8放入
  EnQueue(Queue1,3);//將3放入
  EnQueue(Queue1,2);//將2放入
  printf("%d ",DeQueue(Queue1));
  printf("%d ",DeQueue(Queue1));
  printf("%d ",DeQueue(Queue1));
  system("pause");
}

Note:以上便是队列的基本介绍,包括队列的概念以及应用,最后介绍了,队列的几种常见实现方式。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值