前面用顺序存储的方式实现了队列,顺序存储的方式存在着缺点,在出队时要移动大量的元素,在大数据量时需要消耗大量的资源。针对此采用链式存储的方式实现队列。其结构组成如下,需要重点说明的是增加了length,其表示结点的个数,一般书上没有这个元素,Martin老师加上的,确实好用!
typedef struct _linlList {
datatype data;
_linlList* next;
}linkList;
typedef struct _linkQueue {
int length;
linkList* front;
linkList* rear;
}linkQueueNode,linkQueue;
用图表示更加直观:
由结构体组成和图可以看出,头结点是带有两个指针 front和 rear,分别指向第一个结点和最后一个结点,length是结点的个数,初始化为0。结点的组成是链式结构,由数据data和next指针组成。在前期搞明白单链式结构的基础上,相应的操作就变得很简单了。初始化函数如下
bool initLinkQueue(linkQueue* &lq) {
lq = new linkQueue;
if (!lq) return false;
lq->length = 0;
lq->front = lq->rear = NULL;
return true;
}
其他的操作都是常规的,入队、出队、遍历、获取头元素等等。整个代码如下,亲测可过
#include<Windows.h>
#include<iostream>
#define MAX_SIZE 10
using namespace std;
typedef int datatype;
typedef struct _linlList {
datatype data;
_linlList* next;
}linkList;
typedef struct _linkQueue {
int length;
linkList* front;
linkList* rear;
}linkQueueNode,linkQueue;
bool initLinkQueue(linkQueue* &lq);//链式队列初始化
bool linkQueueEnter(linkQueue*& lq, datatype data);//入队
void linkQueuePrint(linkQueue*& lq);
bool linkQueueDelete(linkQueue*& lq, datatype* data);//出队
bool linkQueueGetHead(linkQueue*& lq, datatype* data);//获取队首的元素,不出队
void linkQueueClear(linkQueue*& lq);//清空队列
int linkQueueGetLength(linkQueue*& lq);//获取队列的长度
void linkQueueDestroy(linkQueue*& lq);//销毁列表
int main() {
linkQueue* lq=NULL;
initLinkQueue(lq);
int i;
for (i = 0; i < 15; i++) {
if (linkQueueEnter(lq, i)) {
cout << "入队成功!" << endl;
}
else {
cout << "入队失败!" << endl;
}
}
linkQueuePrint(lq);
cout << "***********出队******************" << endl;
datatype* data=new int ;
for (int i = 0; i < 5; i++) {
if (linkQueueDelete(lq, data)) {
cout << "出队的元素是" << *data << endl;
}
else {
cout << "出队失败!" << endl;
}
}
if (linkQueueGetHead(lq, data)) {
cout << "获取队列首元素是:" << *data << endl;
}
cout << "队列的长度为:" << linkQueueGetLength(lq)<<endl;
linkQueueClear(lq);
cout << "清空后队列的长度为:" << linkQueueGetLength(lq)<<endl;
linkQueueDestroy(lq);
system("pause");
return 0;
}
bool initLinkQueue(linkQueue* &lq) {
lq = new linkQueue;
if (!lq) return false;
lq->length = 0;
lq->front = lq->rear = NULL;
return true;
}
bool linkQueueEnter(linkQueue*& lq, datatype data) {
if (!lq || lq->length == MAX_SIZE) return false;
linkList* node = new linkList;
node->data = data;
node->next = NULL;
if (!lq->front) {
lq->rear=lq->front = node;
}
else {
lq->rear->next = node;
lq->rear = node;
}
lq->length++;
return true;
}
void linkQueuePrint(linkQueue*& lq) {
if (!lq) return ;
if (!lq->length) {
cout << "队列长度为0" << endl;
return;
}
linkList* tmp = lq->front;
while(tmp) {
cout << tmp->data << " ";
tmp = tmp->next;
}
cout << endl;
}
bool linkQueueDelete(linkQueue*& lq, datatype* data) {
if (!lq || !lq->length) return false;
*data = lq->front->data;
linkList* tmp = lq->front;
lq->front = tmp->next;
delete tmp;
lq->length--;
return true;
}
bool linkQueueGetHead(linkQueue*& lq, datatype* data) {
if (!lq || !lq->length) return false;
*data = lq->front->data;
return true;
}
int linkQueueGetLength(linkQueue*& lq) {
if (!lq) return -1;
return lq->length;
}
void linkQueueClear(linkQueue*& lq) {
if (!lq || !lq->length) return;
linkList* tmp = NULL;
while (lq->front) {
tmp = lq->front->next;
delete lq->front;
lq->front = tmp;
}
lq->front = lq->rear = NULL;
lq->length = 0;
}
void linkQueueDestroy(linkQueue*& lq) {
if (!lq || !lq->length) return;
linkList* tmp = lq->front;
while (lq->front) {
tmp = lq->front->next;
delete lq->front;
lq->front = tmp;
}
delete lq->front;
delete lq->rear;
delete lq;
}