基本数据结构之队列
2013-08-24 09:36
316 查看
一、基本数据结构之队列
队列作为计算机系统一种非常常见的数据结构被大家所熟知。同堆栈一样,队列也是有插入和删除只能在限定段的线性表。
队列是一种FIFO(First In First Out)的线性表。具体通常用链表或数组来实现。队列只允许在后端(rear)进行插入操作,在前段(front)进行删除操作。
队列的操作方式和堆栈类似,唯一的区别就是队列只允许在后端进行数据添加。
队列通常能够解决一下问题:
1)解决主机与外部设备之间速度不匹配的问题。设置一个缓冲队列。
2)解决因多用户引起的资源竞争问题。系统按照请求时间设置一个请求队列(还可以给每个任务加一个优先级,就成为了优先级队列)。
下面介绍队列的几种常见的实现方式:
队列作为计算机系统一种非常常见的数据结构被大家所熟知。同堆栈一样,队列也是有插入和删除只能在限定段的线性表。
队列是一种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:以上便是队列的基本介绍,包括队列的概念以及应用,最后介绍了,队列的几种常见实现方式。
相关文章推荐
- 数据结构-循环队列的基本实现操作
- 【数据结构】用C++编写队列及基本操作(包括插入,出队列,摧毁,清空等等)
- 数据结构-链队列的基本操作
- 基本数据结构——队列的顺序表示
- 数据结构--顺序队列基本操作
- 跟着郝斌学数据结构(06)——队列(数组队列基本的一些问题)
- “栈与队列”之栈--基本数据结构
- 数据结构-链队列的基本操作
- 基本数据结构-队列
- 数据结构——基本数据结构之队列
- 算法导论 第三部分——基本数据结构——栈、队列、链表、散列表
- 基本数据结构 - 栈和队列
- 【数据结构】 队列的基本操作
- “栈和队列”之队列--基本数据结构
- JS的基本数据结构实现---栈和队列
- 第九篇:基本数据结构——队列的链式表示
- Python实现基本数据结构---队列操作
- 【数据结构】 栈和队列 YTU 2248: 栈的基本运算(栈和队列)
- 数据结构 队列的基本操作
- 【数据结构与算法】基本数据结构——队列的链式表示