队列(Queue)
最近学习了数据结构队列,队列是一种特殊的线性表,是被限定了的线性表,先进先出(FIFO, First in First out),跟栈的后进先出(LIFO, Last in First out)是类似的一种数据结构,对于这个数据结构,已经有很多的文章有过介绍了,这里也就不再赘述,直接贴出代码,希望能够互相进步!
这里使用了一个HeadNode的节点来表示一个队列,里面只有两个信息,分别是指向队列队首和指向队列队尾的两个指针,这样写,个人认为会更加方便,也不需要进行一些指针的返回。
#include <cstdlib> #include <iostream> using namespace std; typedef int Elemtype; typedef struct node{ Elemtype data; node *next; }Queue; typedef struct{ Queue *front, *end; }HeadNode; /* *1.初始化一个队列 *2.入队 *3.出队 *4.获取队首元素 *5.判断队列是否为空 */ bool isEmpty(HeadNode *hd) { return (hd -> front == NULL ? true : false); } HeadNode *initQueue() { HeadNode *p = new HeadNode; if (p == NULL) { cout << "分配内存失败!请重试!" << endl; exit(-1); } p -> front = NULL; p -> end = NULL; cout << "初始化成功!" << endl; return p; } void pushQueue(HeadNode *hd, Elemtype e) { Queue *p = new Queue; if (p == NULL) { cout << "分配内存失败!请重试!" << endl; exit(-1); } p -> next = NULL; p -> data = e; if(hd -> end != NULL) hd -> end -> next = p; hd -> end = p; if (hd -> front == NULL) { hd -> front = p; } cout << "入队成功!" << endl; } void popQueue(HeadNode *hd) { if (isEmpty(hd)) { cout << "该队列为空!不能进行出队操作!" << endl; } Queue *q = hd -> front; Queue *p = q -> next; hd -> front = p; delete q; cout << "出队成功!" << endl; } Elemtype frontQueue(HeadNode *hd) { if (isEmpty(hd)) { cout << "该队列为空!不能查询队首元素" << endl; return -1; } return hd -> front -> data; } int main() { HeadNode *hd = initQueue(); for (int i = 0; i < 10; ++i) { srand(i); Elemtype data = rand() % 100; pushQueue(hd, data); cout << "第 " << i + 1 << " 个元素是 " << data << endl; } cout << "该队列是否为空? " << (isEmpty(hd) ? "True" : "False") << endl; if (!isEmpty(hd)) { cout << "该队列元素为: " << endl; for (int i = 0; i < 10; ++i) { Elemtype data = frontQueue(hd); cout << "第 " << i + 1 << " 个元素是 " << data << endl; popQueue(hd); } } system("pause"); return 0; }
只写了一些最基本的操作,以后如果可以,再进行添加吧。
上面的写法是使用链式存储结构,下面是使用顺序存储结构,不多说,还是直接附代码
因为顺序存储结构的原因,无论是仅让front或是end指针移动,或是将整个表移动,都不是非常合理的方式,所以,用单向循环列表相对来说是最好的方式了。
/* *1.初始化一个队列 *2.入队 *3.出队 *4.获取队首元素 *5.判断队列是否为空 *6.判断队列是否为满 */ #include <cstdlib> #include <cstring> #include <iostream> using namespace std; #define MAXN 2000 typedef int Elemtype; typedef struct { Elemtype data[MAXN]; int front, end; }SqQueue; /* 1.front是队首元素的索引。 2.end是队尾元素的下一个位置的索引 3.队满的条件是front = end,且front位置的data不为-1 4.队空的条件是front = end,且front位置的data是-1 */ bool isEmpty(SqQueue sq) { if (sq.front == sq.end && sq.data[sq.front] == -1) { return true; } else { return false; } } bool isFull(SqQueue sq) { if (sq.front == sq.end && sq.data[sq.front] != -1) { return true; } else { return false; } } SqQueue init(SqQueue sq, int n) { memset(sq.data, -1, sizeof(sq.data)); sq.front = 0, sq.end = 0; for (int i = 0; i < n; ++i) { cout << "请输入队列元素:"; cin >> sq.data[i]; sq.end = (sq.end + 1) % MAXN; } return sq; } SqQueue push(SqQueue sq, Elemtype elem) { if (isFull(sq)) { cout << "该队列已满!请检查后继续!" << endl; return sq; } sq.data[sq.end] = elem; sq.end = (sq.end + 1) % MAXN; cout << "已将元素 " << elem << " 插入队尾" << endl; return sq; } SqQueue pop(SqQueue sq) { if (isEmpty(sq)) { cout << "该队列已空!请检查后继续!" << endl; return sq; } sq.data[sq.front] = -1; sq.front = (sq.front + 1) % MAXN; cout << "已将队首元素出队!" << endl; return sq; } Elemtype front(SqQueue sq) { if (isEmpty(sq)) { cout << "该队列已空!请检查后继续!" << endl; return -1; } return sq.data[sq.front]; } int main() { SqQueue q; q = init(q, MAXN); q = push(q, 5); q = pop(q); q = push(q, 5); cout << "队列Q的队首元素为: " << front(q) << endl; return 0; }
这个数据结构不是很困难,在理解链表的基础上加以限制就好了。对于栈和队列,都是一种受限的线性表。所以如果想学好栈和队列的话还是需要去把链表学好。这里贴一个以前看的一个链表写的不错的。
http://www.cnblogs.com/wireless-dragon/p/5170565.html
虽然没有详细的解释链表啊什么的。但是配合着书本以及百度百科,代码等,应该能够对链表有一定得来了解吧。