队列(C++)

#include<iostream>		//队列(C++),Q为头结点
using namespace std;	// Q->front->next->data 为第一个元素
#include <malloc.h>		// Q->rear->data 为最后一个元素

//typedef struct BiTNode {	//测试存放的指针类型
//	int data;
//	struct BiTNode* lchild, * rchild;
//}BiTNode, * BiTree;
//
//BiTree createb(BiTree T) {
//	T->data = 1;
//	T->lchild = (BiTree)malloc(sizeof(BiTNode));
//	T->rchild = (BiTree)malloc(sizeof(BiTNode));
//	T->lchild->data = 2;
//	T->rchild->data = 3;
//	return T;
//}

typedef int ElemType;	//用来更换队列存储的数据类型,可以是char、指针等

typedef struct Node {	//存放数据域和指针域(辅)
	ElemType data;
	struct Node* next;
}QNode, * QueuePtr;

typedef struct {	//队列的头尾指针(主)
	QueuePtr front;
	QueuePtr rear;
}LinkQ, * LinkQueue;

LinkQueue InitQueue() {		//构造空队列
	LinkQueue Q;
	//Q = (LinkQueue)malloc(sizeof(LinkQ));
	Q = new LinkQ();
	//Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
	Q->front = Q->rear = new QNode();
	Q->front->next = NULL;
	return Q;
}

void PrintQueue(LinkQueue Q) {	//输出队列
	//注:此处若不用临时指针q1->front指向Q->front的话,若直接用Q->front,那么
	//	  Q->front的地址会改变,调用此函数后,指向的就不是队列的头结点了
	//详见下面的function()函数
	LinkQueue q1;
	//q1 = (LinkQueue)malloc(sizeof(LinkQ));
	q1 = new LinkQ();
	q1->front = Q->front;
	while (q1->front->next) {
		//注:若调用BiTree,则此处还要后加->data
		//因为此时q1->front->next->data存储的是BiTree型指针
		cout << q1->front->next->data << " ";
		q1->front = q1->front->next;
	}
}

void DestroyQueue(LinkQueue Q) {	//销毁队列
	while (Q->front) {
		Q->rear = Q->front->next;
		free(Q->front);
		Q->front = Q->rear;
	}
}

void push(LinkQueue Q, ElemType e) {  //插入元素e为队尾元素
	//QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
	QueuePtr p = new QNode();
	p->data = e;
	p->next = NULL;
	Q->rear->next = p;
	Q->rear = p;
}

void pop(LinkQueue Q) {		//移除队列第一个元素
	Q->front = Q->front->next;
}

ElemType Q_front(LinkQueue Q) {		//返回队头元素
	if (Q->front == Q->rear) return 0;
	ElemType e = Q->front->next->data;
	return e;
}

ElemType Q_back(LinkQueue Q) {		//返回队尾元素
	if (Q->front == Q->rear) return 0;
	ElemType e = Q->rear->data;
	return e;
}

int Q_size(LinkQueue Q) {	//返回队列长度
	LinkQueue q1;
	//q1 = (LinkQueue)malloc(sizeof(LinkQ));
	q1 = new LinkQ();
	q1->front = Q->front;
	int length = 0;
	while (q1->front->next) {
		length++;
		q1->front = q1->front->next;
	}
	return length;
}

int empty(LinkQueue Q) {	//判断队列是否为空,是—1,否—0
	if (Q->front == Q->rear)
		return 1;
	else
		return 0;
}


//证明:1.移动前后,头结点q1和Q都不会变(q1和Q仅仅代表结构体,不是头指针)
//	2.移动后,当定义q1 = Q时:q1->front和Q->front同步同地址变化(因为二者从根源上相同)
//	          当定义q1->front = Q->front(q1->front头指针指向Q->front头指针)时:q1->front变,Q->front不变
//	  移动本质:定义另一个指针q1->front指向Q->front,q1->front的移动,不会影响到Q->front
//	3.只是q1->front移动,q1->front地址改变,但不会改变头结点q1(结构体)的地址
void function(LinkQueue Q) {
	LinkQueue q1;
	q1 = InitQueue();
	*q1 = *Q;		//相当于把Q完全复制一份给q1,q1的操作不会影响到Q
	cout << "移动前,q1地址:" << q1 << endl;
	cout << "移动前, Q地址:" << Q << endl;
	cout << "移动前,q1->front地址:" << q1->front << endl;
	cout << "移动前, Q->front地址:" << Q->front << endl;
	q1->front = q1->front->next;
	cout << endl;
	cout << "移动后,q1地址:" << q1 << endl;
	cout << "移动后, Q地址:" << Q << endl;
	cout << "移动后,q1->front地址:" << q1->front << endl;
	cout << "移动后, Q->front地址:" << Q->front << endl;
}

int main() {
	/*LinkQueue Q;
	Q = InitQueue();
	BiTree T;
	//T = (BiTree)malloc(sizeof(BiTNode));
	T = new BiTNode();
	T = createb(T);
	push(Q, T);
	push(Q, T->lchild);
	push(Q, T->rchild);
	PrintQueue(Q);
	return 0;*/
	int i, j, temp, number;
	LinkQueue Q;
	Q = InitQueue();
	cin >> number;
	for (i = 0; i < number; i++) {
		cin >> temp;
		push(Q, temp);
	}
	function(Q);
	return 0;
}

测试结果:

 

#include #include #include //队列最大长度 #define MAX_QUEUE 1024 //偷懒,就用静态队列了 static int mQueue[MAX_QUEUE]; //队列插入 void InsertData(int **Front, int **Rear) { if (*Rear + 1 == *Front && (*Rear + 1 - MAX_QUEUE != *Front)) { //当队列数据已满,返回 puts("Queue Size Overflow!\n"); return; } else if (*Rear - mQueue > MAX_QUEUE) { //实现的是类似循环队列,但由于是静态线性队列(数组) //而不是用链表来实现的,所以到静态队列(数组)尾部,尾指针自动指向(数组)头部 *Rear = mQueue; } puts("Input Data:"); scanf("%d", *Rear); //输入数据后,尾指针后移 *Rear += 1; } //从头指针删除一个队列中的数据 void DeleteData(int **Front, int **Rear) { if (*Front == *Rear) { //头指针尾指针重合,队列空,不能删除,返回 puts("Queue Empty!\n"); return; } else if (*Front - mQueue > MAX_QUEUE) { //参考 Rear *Front = mQueue; } //从头指针删除一个数据 *Front += 1; } //显示队列数据 void ShowData(int **Front, int **Rear) { int *temp; for (temp=*Front; temp!=*Rear; temp++) { printf("%d --> ", *temp); } puts("\n"); } void usage(void) { puts("1. Insert Data"); puts("2. Delete Data"); puts("3. Show Data"); } int main(int argc, char **argv) { //头指针,尾指针 //队列的一个特性 First in first out FIFO int *pFront, *pRear; int op_code; //初始化队列,头指针和尾指针此时指向的地址相同 pFront = pRear = mQueue; while (1) { usage(); scanf("%d", &op_code); switch (op_code) { case 1: printf("%p\n", pFront); printf("%d\n", *pFront); InsertData(&pFront, &pRear); break; case 2: DeleteData(&pFront, &pRear); break; case 3: ShowData(&pFront, &pRear); break; default: break; } } return 0; }
顺序队列是一种基于数组实现的队列,它的特点是先进先出,即先进入队列的元素先出队列。下面是一个简单的顺序队列的实现,使用C++语言: ```cpp const int MAXSIZE = 100; // 队列最大容量 class SeqQueue { private: int data[MAXSIZE]; // 存储队列元素的数组 int front; // 队头指针 int rear; // 队尾指针 public: SeqQueue() { front = rear = -1; // 初始化队头和队尾指针 } bool isEmpty() { return front == rear; // 队列为空的条件是队头指针和队尾指针相等 } bool isFull() { return rear == MAXSIZE - 1; // 队列已满的条件是队尾指针指向数组的最后一个元素 } bool enQueue(int x) { // 入队操作 if (isFull()) return false; // 如果队列已满,返回false rear++; // 队尾指针加1 data[rear] = x; // 将元素x存入队尾指向的位置 return true; } bool deQueue(int& x) { // 出队操作 if (isEmpty()) return false; // 如果队列为空,返回false front++; // 队头指针加1 x = data[front]; // 取出队头元素 return true; } }; ``` 在这个实现中,我们将队列元素存储在一个数组中,使用front和rear分别指向队列的头部和尾部。isEmpty和isFull方法用于判断队列是否为空或已满。enQueue方法用于将元素加入队列尾部,deQueue方法用于从队列头部取出元素。 需要注意的是,这个实现中没有考虑队列的扩容问题,如果队列已满,入队操作将会失败。在实际应用中,需要根据具体情况来进行扩容操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值