数据结构基本内容(第四篇:队列)

队列 Queue

FIFO

操作集:长度为MaxSize的队列Q  Queue,队列元素item  ElementType

  1. Queue CreatQueue( int MaxSize ):生成长度为MaxSize的空队列;

  2. int IsFullQ( Queue Q, int MaxSize ):判断队列Q是否已满;

  3. void AddQ( Queue Q, ElementType item ): 将数据元素item插入队列Q中;

  4. int IsEmptyQ( Queue Q ): 判断队列Q是否为空;

  5. ElementType DeleteQ( Queue Q ):将队头数据元素从队列中删除并返回。

队列的顺序存储实现

一个一维数组,队列头元素位置的变量front, 队列为元素位置的变量rear, 而堆栈由一个一位数组加上一个top.

队列的结构

```c

#define MaxSize <储存数据元素的最大个数>

struct QNode {

ElementType Data[ MaxSize ];

int rear;

int front;

};

typedef struct QNode *Queue;

```

循环队列

当front == rear时候, 空

rear指向这个队列实际的最后一个元素的位置,front是第一个元素的前一个. 加入一个元素的时候rear + 1, 删除一个元素的时候front + 1

使用额外标记 size或者tag

仅使用n-1个数组空间

* 创建队列

```c

Queue CreateQueue(int Maxsize)

{

Queue Q = (Queue)malloc(sizeof(struct QNode));

Q->Data = (ElementType)malloc(Maxsize * sizeof(ElementType));

Q->front = Q->rear = 0;

Q->Maxsize = Maxsize;

return Q;

}

```

* 入队列

用求余数函数,实现循环队列 例如 (5+1)%6 = 0, 放在第0位

```c

void AddQ( Queue PtrQ, ElementType item) {

if ( (PtrQ->rear+1) % MaxSize == PtrQ->front ) // front rear相邻

{

printf("队列满");

return;

}

PtrQ->rear = (PtrQ->rear+1)% MaxSize;

PtrQ->Data[PtrQ->rear] = item;

}

```

* 出队

```c

ElementType DeleteQ ( Queue PtrQ ) // front和rear相同

{

if ( PtrQ->front == PtrQ->rear )

{

printf("队列空");

return ERROR;

}

else

{

PtrQ->front = (PtrQ->front+1)% MaxSize; // front往后移一位指向第一个元素

return PtrQ->Data[PtrQ->front];

}

}

```

队列的链式存储实现

链表结点结构

```c

struct Node{

ElementType Data;

struct Node *Next;

};

```

链表队列结构

```c

struct QNode

{

struct Node *rear; /* 指向队尾结点 */

struct Node *front; /* 指向队头结点 */

};

typedef struct QNode *Queue;

Queue PtrQ; // 包含front和rear的这个结构的指针PtrQ

```

* 出队

```c

ElementType DeleteQ ( Queue PtrQ )

{

struct Node *FrontCell;

ElementType FrontElem;

if ( PtrQ->front == NULL)

{

printf("队列空");

return ERROR;

}

FrontCell = PtrQ->front; // 找到队列的头个元素

if ( PtrQ->front == PtrQ->rear) /* 若队列只有一个元素 */

PtrQ->front = PtrQ->rear = NULL; /* 删除后队列置为空 */

else

PtrQ->front = PtrQ->front->Next;

FrontElem = FrontCell->Data;

free( FrontCell ); /* 释放被删除结点空间 */

return FrontElem;

}

```

应用: 多项式加法运算

算法思路:

两个指针P1和P2分别指向这两个多项式第一个结点,不断循环:

* P1->expon==P2->expon相同: 系数相加,若结果不为0,则作为结果多项式对应项

的系数。同时,P1和P2都分别指向下一项;

* P1->expon>P2->expon 这时p1大: 将P1的当前项存入结果多项式,并使P1指向下一项;

* P1->expon<P2->expon 这时p2大: 将P2的当前项存入结果多项式,并使P2指向下一项;

* 当某一多项式处理完时,将另一个多项式的所有结点依次复制到结果多项式中去。

```c

struct PolyNode //结构类型

{

int coef; // 系数

int expon; // 指数

struct PolyNode *link; // 指向下一个节点的指针

}

typedef struct PolyNode *Polynomial;

Polynomial P1, P2; // p1 p2都是这种结构的指针

```

实现

```c

Polynomial PolyAdd (Polynomial P1, Polynomial P2)

{

Polynomial front, rear, temp; // 结构多项式的头 尾.

int sum;

// 临时空结点点作为结果多项式的表头, front rear都指向这个空间点

rear = (Polynomial) malloc(sizeof(struct PolyNode));

front = rear; /* 由front 记录结果多项式链表头结点 */

while ( P1 && P2 ) /* 当两个多项式都有非零项(都不空)待处理时 */

switch ( Compare(P1->expon, P2->expon) ) // 比较两个指数

{

case 1: // p1大

// 系数和指素接到rear的后面

Attach( P1->coef, P1->expon, &rear);

P1 = P1->link;

break;

case -1: // p2大

Attach(P2->coef, P2->expon, &rear);

P2 = P2->link;

break;

case 0: //p1 = p2

sum = P1->coef + P2->coef;

// 判断sum不等于0

if ( sum ) Attach(sum, P1->expon, &rear);

P1 = P1->link;

P2 = P2->link;

break;

}

/* 将未处理完的另一个多项式的所有节点依次复制到结果多项式中去 */

// p1不空

for ( ; P1; P1 = P1->link )

Attach(P1->coef, P1->expon, &rear);

// p2 不空

for ( ; P2; P2 = P2->link )

Attach(P2->coef, P2->expon, &rear);

// rear 指向结果多项式的最后一项,现在结束了,把link设为NULL

rear->link = NULL;

// 释放临时结点

temp = front;

front = front->link; /*令front指向结果多项式第一个非零项 */

free(temp); /* 释放临时空表头结点 */

return front;

}

```

其中attach函数

```c

//传入系数和指数,以及最后一个结点的指针位置(指针的指针),于在本函数中需要改变当前结果表达式尾项指针的值,所以函数传递进来的是结点指针的地址,*pRear指向尾项

void Attach( int c, int e, Polynomial *pRear )

{

Polynomial P;

/* 申请新结点 */

P =(Polynomial)malloc(sizeof(struct PolyNode));

P->coef = c; /* 对新结点赋值 */

P->expon = e;

P->link=NULL;

/* 将P指向的新结点插入到当前结果表达式尾项的后面 */

(*pRear)->link = P;

*pRear = P; /* 修改pRear值 */

}

```

相关推荐
躲着人群32 分钟前
次短路&&P2865 [USACO06NOV] Roadblocks G题解
c语言·数据结构·c++·算法·dijkstra·次短路
蓝风破云3 小时前
C++实现常见的排序算法
数据结构·c++·算法·排序算法·visual studio
浩浩测试一下4 小时前
06高级语言逻辑结构到汇编语言之逻辑结构转换 for (...; ...; ...)
汇编·数据结构·算法·安全·web安全·网络安全·安全架构
封奚泽优6 小时前
MATLAB入门教程
数据结构·matlab·deepseek
野生的编程萌新7 小时前
【数据结构】从基础到实战:全面解析归并排序与计数排序
数据结构·算法·排序算法
whitepure9 小时前
万字详解常用数据结构(Java版)
java·数据结构·后端
2025年一定要上岸10 小时前
【数据结构】-4-顺序表(上)
java·开发语言·数据结构
Vect__1 天前
链表漫游指南:C++ 指针操作的艺术与实践
数据结构·c++·链表
古译汉书1 天前
蓝桥杯算法之基础知识(2)——Python赛道
数据结构·python·算法·蓝桥杯
.Vcoistnt1 天前
Codeforces Round 1043 (Div. 3)(A-E)
数据结构·算法