C/C++泛型编程实现数据结构之队列

#C/C++泛型编程实现数据结构之队列

早在曾经一篇博文中,我曾介绍过顺序存储和链式存储的区别和好处,博文传送门:https://blog.csdn.net/qq_27180763/article/details/82683029

本章将讲诉:

  1. 队列的逻辑结构刨析
  2. 顺序存储结构下的循环队列
  3. 链式存储结构下的循环链队列
  4. C/C++泛型编程类模板实现队列

###逻辑结构:
顺序队列的逻辑结构:

#define Max_Size = 100;
template 
struct Queue{
	DataType data[Max_Size];
	int front;
	int rear;
};

由于队列是一种先进先出的FIFO的线性表,所以我们在这里设置了队列的头front和队列的尾部rear;从而实现rear进入的元素可以在front处删除。下面来看链队列的逻辑结构。

链队列的逻辑结构:

struct QueueNode{
		DataType data;
		QueueNode* next;
	};
struct LinkQueue{
		QueueNode* front;
		QueueNode* rear;
	};
LinkQueue Q;

其中Queue_Node这个结构题代表了每个节点的类型,顺序存储中我们采用数组来实现这个队列空间,而在这里我们采用了链表来实现这个访问受限的线性表。

###入队列和出队列
这里入队和出队操作要单独拿出来讲。
由于循环队列的入队和出队是循环意义上的入队和出队,为了充分利用数组空间,克服上溢,可将数组空间想象成一个环状空间,并称这个环状空间为循环队列。这种循环队列的出队和入队运算时,头尾指针仍然要加1,只不过当头尾指针指向数组上界Queue_Size-1时,如何按正常的操作进行+1运算,则数组就会产生溢出。因此需要判断+1后是否超过数组上界。
顺序队列入队列和出队列实现:

void En_Queue(DataType info) {
		if(!Queue_full()){
			data[rear] = info;
			rear = (rear + 1) % QueueSize;
		}
		else {
			cout << "the Queue is overflow!" << endl;
		}
	}

	DataType De_Queue() {
		if (!Empty_Queue()){
			DataType x = data[front];
			front = (front + 1) % QueueSize;
			return x;
		}
		else {
			cout << "the Queue is Empty!" << endl;
			exit(0);
		}
	}

链队列入队和出队实现:

void EnQueue(DataType x) {
		QueueNode* p = (QueueNode*)malloc(sizeof(QueueNode));
		p->data = x;
		p->next = NULL;
		Q->rear->next= p;
		Q->rear = p;
	}
DataType DeQueue() {
		QueueNode* p;
		if (QueueEmpty()) {
			cout << "the Queue is empty!" << endl;
			exit(0);
		}
		else {
			p = Q->front;
			Q->front = Q->front->next;
			free(p);
			return Q->front->data;
		}
	}

###以上即为重点部分,现在来看完整代码实现:

###顺序存储结构下的队列:

template 
class Queue {
private:
	const int QueueSize = 100;

protected:
	DataType data = new DataType[QueueSize];
	int front, rear;

public:
	Queue() {
		front = rear = 0;
	}

	void En_Queue(DataType info) {
		if(!Queue_full()){
			data[rear] = info;
			rear = (rear + 1) % QueueSize;
		}
		else {
			cout << "the Queue is overflow!" << endl;
		}
	}

	DataType De_Queue() {
		if (!Empty_Queue()){
			DataType x = data[front];
			front = (front + 1) % QueueSize;
			return x;
		}
		else {
			cout << "the Queue is Empty!" << endl;
			exit(0);
		}
	}

	bool Empty_Queue() {
		return rear == front;
	}

	bool Queue_full() {
		return (rear + 1) % QueueSize == front;
	}
};

###链式存储结构下的队列:

template 
class Link_Queue{
private:
	struct QueueNode{
		DataType data;
		QueueNode* next;
	};
protected:
	struct LinkQueue{
		QueueNode* front;
		QueueNode* rear;
	};

private:
	LinkQueue* Q;
public:
	Link_Queue() {
		Q->front = (QueueNode*)malloc(sizeof(QueueNode));
		Q->rear = Q->front;
		Q->rear->next = NULL;
	}

	bool QueueEmpty() {
		return Q->rear == Q->front;
	}
	
	void EnQueue(DataType x) {
		QueueNode* p = (QueueNode*)malloc(sizeof(QueueNode));
		p->data = x;
		p->next = NULL;
		Q->rear->next= p;
		Q->rear = p;
	}

	DataType GetFront() {
		if (QueueEmpty()) {
			cout << "the Queue is Empty!" << endl;
			exit(0);
		}
		else {
			return Q->front->next->data;
		}
	}

	DataType DeQueue() {
		QueueNode* p;
		if (QueueEmpty()) {
			cout << "the Queue is empty!" << endl;
			exit(0);
		}
		else {
			p = Q->front;
			Q->front = Q->front->next;
			free(p);
			return Q->front->data;
		}
	}
};

你可能感兴趣的:(C/C++,数据结构,C/C++应用编程)