数据结构-队列
来源:互联网 发布:网络电话卡怎么使用 编辑:程序博客网 时间:2024/06/04 19:09
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。队列的实现有顺序队列、循环队列和链表队列。这里我用了循环队列和链表队列两种。
顺序队列:
与顺序表一样,顺序队列需要分配一块连续的区域来存储队列的元素,需事先定义数据大小。当队列满入队是会出现上溢的现象,队列空出队会产生下溢的想象。这是后要想继续操作,需要对数据进行移动,效率不佳。
循环队列:
循环队列多使用一个数据大小的空间用来表示队列空或者队列满。也就是说循环队列的存储空间中最大数据个数加一(倘若不牺牲着一个数据大小的空间,就需要额外声明一个标志位flag。初始情况下flag=0,front=rear表示队列空。第二次front=rear,flag=1,表示队列满)。循环队列中中有三种状态:
- front==rear ( 队列为空状态 )
- front!=(rear+1)%maxSize ( 队列的一般状态 )
- front==(rear+1)%maxSize ( 队列为满的状态 )
如下图所示,循环队列中能存取的最大数据个数为7个,但需要申请8个数据大小的空间。第一种情况中:队列中没有数据,此时front=rear=0,队列为空;第二种情况中:队列中有一个数据,front=0、rear=1,队列处于一般状态,既能进队也能出队;第三种情况:队列满,front=0,rear=7,此时满足front=(rear+1)%maxSize。在队列常用的操作:打印、入队、出队、获取队头、队尾数据值中。打印、入队、出队、获取队尾数据值中要注意该队列是循环队列,可能出现rear>front的情况,需要处理一下。
代码:
#include<iostream>using namespace std;class arrayQueue{ int front; int rear; int* queue; int maxSize;public: arrayQueue() {} arrayQueue(int maxS) { front = rear = 0; queue = new int[maxS+1]; maxSize = maxS+1; } ~arrayQueue() { del(); } void dis();//打印队列元素 void del();//删除 void push(int item);//item入队 void pop();//出队 void creat(int num);//创建num个元素的测试队列 bool isEmpty();//是否空 bool isFull();//是否空 bool getFront(int &val);//读取队头元素 bool getRear(int &val);//读取队尾元素};void arrayQueue::dis(){ if (!isEmpty()) { for (int i = front;i != rear;i=(i+1)%maxSize) { if ((i + 1) % maxSize != rear) { cout << queue[i] << "->"; } else cout << queue[i] << endl; } } else cout << "队列空。" << endl;}void arrayQueue::del(){ delete[] queue; front = rear = maxSize = 0;}void arrayQueue::push(int item){ if (!isFull()) { queue[rear] = item; rear =(rear+1)%maxSize; } else { cout << "队列满。" << endl; }}void arrayQueue::pop(){ if (!isEmpty()) { front = (front +1) % maxSize; } else { cout << "队列空。" << endl; }}void arrayQueue::creat(int num){ for (int i = 0;i < num;i++) push(i+1);}bool arrayQueue::isEmpty(){ return front == rear;}bool arrayQueue::isFull(){ return (rear + 1) % maxSize == front;}bool arrayQueue::getFront(int& val){ if (!isEmpty()) { val = queue[front]; return true; } else { cout << "队列空。" << endl; return false; }}bool arrayQueue::getRear(int& val){ if (!isEmpty()) { val = queue[(rear-1+maxSize)%maxSize]; cout << val << endl; return true; } else { cout << "队列空。" << endl; return false; }}int main(){ int a; arrayQueue t(20); t.creat(20); t.dis(); return 0;}
链表队列:
链式队列是基于单链表的存储表示,队头指针front指向队头结点,队尾指针rear指向队尾结点。链表中所有的结点都必须通过这两个指针访问到,并且队头端只能用来删除结点,队尾端用来插入结点。如下图所示:n个元素的队列中,队头指针指向链表中第一个数据、队尾指针指向链表中最后一个数据,其中出、入队方向就是箭头描述的方向。
代码:
#include<iostream>using namespace std;class queNode{public: int element; queNode* next; queNode() {} queNode(int e, queNode* n) :element(e), next(n) {}};class queList{public: queNode* front; queNode* rear; int length; queList() {} ~queList() { del(); } void dis();//打印队列元素 void del();//删除 void push(int item);//item入队 void pop();//出队 void creat(int num);//创建测试队列 bool isEmpty();//是否空 bool getFront(int &val);//读取队头元素 bool getRear(int &val);//读取队尾元素};void queList::dis(){ if (!isEmpty()) { queNode* t = front; while (t != NULL) { if (t->next != NULL) { cout << t->element<< "<-"; } else { cout << t->element << endl; } t = t->next; } } else { cout << "队列空。" << endl; }}void queList::del(){ if (!isEmpty()) { while (front != NULL)//每轮循环开始时,t与front的值相等,不存在访问空指针内容 { rear = front; front = front->next; delete(rear); } rear = NULL; length = 0; }}void queList::push(int item){ queNode* newNode = new queNode(item, NULL); if (length != 0) { rear->next = newNode; rear = newNode; } else { front = rear = newNode; } length += 1;}void queList::pop(){ if (!isEmpty()) { queNode* t = front; front = front->next; length -= 1; if (length == 0) rear = NULL; delete(t); }}void queList::creat(int num){ if (num > 0) { for (int i = 1;i <= num;i++) push(i); }}bool queList::isEmpty(){ return (length == 0);}bool queList::getFront(int& val){ if (!isEmpty()) { val = front->element; return true; } else return false;}bool queList::getRear(int& val){ if (!isEmpty()) { val = rear->element; return true; } else return false;}int main(){ queList t; t.creat(10); t.dis(); return 0;}
链式队列中发现了一个以前一直没发现的问题。当一个指针指向的空间已经被释放后,它的值是什么?访问它会怎么样?它的值还是被释放掉的那块空间的地址,访问它程序会崩溃。
- 数据结构---队列
- 数据结构--队列
- 数据结构队列
- 数据结构---队列
- 数据结构(队列)
- 数据结构-队列
- 数据结构---->队列
- 数据结构---队列
- 【数据结构】队列
- 数据结构--队列
- 【数据结构】 队列
- 数据结构 -- 队列
- 数据结构--队列
- 数据结构:队列
- 数据结构 队列
- 数据结构----队列
- 数据结构----队列
- 数据结构-队列
- Ubuntu使用root帐号,并让Xshell, Winscp以root身份登录
- POJ 1845 Sumdiv 二分+因式分解
- 1028. List Sorting
- linux下搭建redis单机版+java连接测试
- you-get视频采集
- 数据结构-队列
- [Java开发] jdk环境搭建+eclipse字体基本设置
- 视频播放---jiecaovideoplayer的使用
- 博客搬家啦!
- LeetCode : Minimum Moves to Equal Array Elements
- poj 3258 River Hopscotch(二分)
- Agile 敏捷项目思想- INVEST
- PAT甲级1010. Radix (25)
- leetcode:Assign Cookies