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

队列 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值 */

}

```

相关推荐
遇见尚硅谷1 小时前
C语言:20250728学习(指针)
c语言·开发语言·数据结构·c++·笔记·学习·算法
yanchao_hu3 小时前
数据结构基础内容(第二篇:线性结构)
数据结构·windows
拳里剑气4 小时前
C语言:顺序表(上)
c语言·开发语言·数据结构·学习方法
积极向上的zzz5 小时前
java中一些数据结构的转换
java·开发语言·数据结构
每天都在想吃啥6 小时前
day22 哈希表和二叉树
数据结构·哈希算法·散列表
Das16 小时前
【初识数据结构】CS61B 中的归并排序和选择排序
数据结构·算法·排序算法
一只小风华~12 小时前
JavaScript:数组常用操作方法的总结表格
前端·javascript·数据结构·vue.js·算法
一匹电信狗12 小时前
【C++】手搓一个STL风格的vector容器
c语言·数据结构·c++·算法·leetcode·stl·visual studio
小小小白的编程日记13 小时前
C语言中的数据结构--栈和队列(2)
c语言·数据结构