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

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

}

```

相关推荐
Pocker_Spades_A13 小时前
【C语言数据结构】第2章:线性表(2)--线性表的顺序存储结构
c语言·数据结构
小许学java17 小时前
七大排序算法的基本原理
数据结构·算法·排序算法
_dindong19 小时前
动规:01背包
数据结构·笔记·学习·算法·leetcode·动态规划·力扣
-雷阵雨-19 小时前
数据结构——排序算法全解析(入门到精通)
java·开发语言·数据结构·排序算法·intellij-idea
LGL6030A20 小时前
数据结构学习(1)——指针、结构体、链表(C语言)
数据结构·学习
蒙奇D索大20 小时前
【数据结构】考研算法精讲:分块查找的深度剖析 | 从“块内无序、块间有序”思想到ASL性能最优解
数据结构·笔记·学习·考研·改行学it
lingchen19061 天前
b = [1 2 3;4 5 6;7 8 9]>> b(2,2)=[ ]??? Subscripted assignme
数据结构·算法
Vect__1 天前
二叉树实战笔记:结构、遍历、接口与 OJ 实战
数据结构·c++·算法
haoly19891 天前
数据结构与算法篇--结构不变式--动态数组
数据结构·不变式