数据结构_线性表_顺序队列_循环队列_链队列
2016-05-09 10:19
531 查看
个位看官,由于队列操作相对简单,我啥也不多说,直接上代码,欢迎验证!!!
#pragma mark --abstract //队列(queue)是只允许在表的一端进行插入,在表的另一端进行删除的线性表,允许插入的一端称为队尾(rear) //允许删除的一端叫做队头(font),不含元素的队列称为空队列 //队列的特点是先进先出(FIFO线性表) #pragma mark --分类 //1.队列的顺序存储结构称为顺序队列(sequential queue),他是由存放队列的一维数组和分别指向队头和队尾的指针组成.通常约定:队尾指针指示的队尾元素在一维数组中的当前位置,队头指针指向队头元素在一维数组中的当前位置的前一个位置 #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #pragma mark --顺序队列的定义 #if 0 #define maxsize 10 //队列可能的最大长度 typedef int elemtype; typedef struct { elemtype elem[maxsize]; int font,rear; }sequeuetp; #endif //假设sa为sequeuetp 的一个变量 //入队操作 //sq.rear=sq.rear+1; //sq.elem[sq.rear]=x; //出队操作 //sq.font=sq.font+1 //空队列sq.font=sq.rear //满栈的sq.rear=maxsize ,这就有假溢出现象,就出现了 //2.循环队列 //循环的表,设想把sq.elem[0]接在sq.elem[maxsize-1]之后,利用取模运算就很容易实现循环意义的加1操作 //入队 //sq.rear=(sq.rear+1)%maxsize //sq.elem[sq.rear]=x; //出队 //sq.font=(sq.font+1)%maxsize //对空sq.rear=sq.font; //队满 (sq.rear+1)%maxsize=sq.font; #pragma mark -------------循环队列的定义-------------------- #define maxsize 11 //(循环队列的最大长度10 +1) typedef int elemtype; typedef struct { elemtype elem[maxsize]; int font,rear; }cqueuetp; #pragma mark --队列的初始化操作 void initQueue(cqueuetp*cq) { cq->font=0; cq->rear=0; } #pragma mark 判断队列是否为空 bool QueueEmpty(cqueuetp*cq) { return (*cq).font==(*cq).rear?true:false; } #pragma mark 求队列的长度 int size(cqueuetp*cq) { // 加上maxsize 时考虑到cq->rear -cq->font<0的情况 return (maxsize+cq->rear-cq->font)%maxsize; } #pragma mark 读取队头的元素 elemtype Head(cqueuetp*cq) { if (cq->rear==cq->font) {//循环队列不为空 return NULL; } else { return cq->elem[cq->font+1]%maxsize; } } #pragma mark 入队操作 void EntrayQueue(cqueuetp*cq,elemtype x) { if ((cq->rear+1)%maxsize==cq->font) { //队满 printf("overflow\n"); } else { cq->rear=(cq->rear+1)%maxsize; cq->elem[cq->rear]=x; } } #pragma mark 出队操作 elemtype DeletQueue(cqueuetp*cq) { if ((*cq).font==(*cq).rear) { return NULL; }else { cq->font=(cq->font+1)%maxsize; return (cq->elem[cq->font]); } } #pragma mark ------------------链队列--------------------- //和栈的顺序存储一样,队列的顺序存储也可能存在溢出的现象,因此考虑队列的链式存储结构 //队列的链式存储结构成为链队列(linked queue),它实际上是一个同时带有头指针和尾指针的单链表, //头指针指向头结点,尾指针指向尾结点,虽然用头指针就可以唯一确定这个单链表,但是插入操作总是在 //队尾进行,如果没有队尾指针,入队的时间复杂程度,将有O(1)升至O(n) //判空的条件 lq.front=lq.rear; #pragma mark --链队列的定义 typedef struct node{ elemtype data; struct node*next;; }nodetype; typedef struct { nodetype *front; nodetype *rear; }lqueue; #pragma mark --初始化 void initLqueue(lqueue*lq) { //设置一个空队列 lq->front=(nodetype*)malloc(sizeof(nodetype)); lq->front->next=NULL; lq->rear=lq->front; } #pragma mark --判空 bool EmptyLqueue(lqueue*lq) { return lq->front==lq->rear?true:false; } #pragma mark --求队长 int lqSize(lqueue*lq) { int i=0; nodetype*p=lq->front->next; while (p) { i++; p=p->next; } return i; } #pragma mark --读取队头元素操作 elemtype getHead(lqueue*lq) { if (lq->front==lq->rear) { return NULL; } else { return lq->front->next->data; } } #pragma mark 入队操作 void EntryQueue(lqueue*lq,elemtype x){ nodetype*s; s=(nodetype*)malloc(sizeof(nodetype)); s->data=x; s->next=NULL; lq->rear->next=s; lq->rear=s; } #pragma mark 出队操作 elemtype delQueue(lqueue*lq){ elemtype x; nodetype*p; if (lq->front==lq->rear) { return NULL; } else { p=lq->front->next; lq->front->next=p->next; if (p->next==NULL) //当链队列中仅有一个结点时,出队时要修改队尾指针 lq->rear=lq->front; x=p->data; free(p); return x; } } #pragma mark 总结 //1>链队列和链栈类似,无需判断栈满的情况 //2>在出队列的时候,原队列只有一个结点时,该结点既是队头也是队尾,姑删除此结点时必须修改队尾指针,且删除此结点后队列变成空 //3>和链栈情况相同,对于链队列,一般不会产生队满,由于队列的长度一般比较大,所以用链式存储结构比顺序存储结构更有利
相关文章推荐
- 数据结构_线性表_顺序存储之1顺序栈2共享栈_链式存储之链栈_栈的应用举例
- 数据结构_线性表_链式存储_双向循环链表的基本操作
- 数据结构的栈和堆
- java实现最大堆数据结构
- java中一些容器底层的数据结构解析
- 数据结构与算法练习-递归
- VIJOS1986 小h的妹子树二
- 数据结构 笔记2 线性表
- VIJOS 1923 漫长的等待
- 数据结构(12):图 深度优先遍历(DFS)
- Java千百问_06数据结构(013)_数组如何传递
- 位运算-Single Number (求一个给定数组的出现次数为单数的那个数)
- 数据结构——排序算法
- 数据结构与算法:C++实现归并排序
- NYOJ 简单数据结构
- 排序算法——快速排序
- 共同学习Java源代码--数据结构--AbstractList抽象类(二)
- 共同学习Java源代码--数据结构--AbstractList抽象类(一)
- 【数据结构】C语言实现栈的进栈,出栈,遍历,清空等操作
- 数据结构与算法练习-二叉树