队列(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

虽然没有详细的解释链表啊什么的。但是配合着书本以及百度百科,代码等,应该能够对链表有一定得来了解吧。

原文地址:https://www.cnblogs.com/wiklvrain/p/8179481.html