当前位置: 首页 > news >正文

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

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

}

```

http://www.dtcms.com/a/301003.html

相关文章:

  • 2025.7.27
  • Java面试题及详细答案120道之(061-080)
  • C++算法竞赛篇(六)一维数组题型讲解
  • 【工具】python汇总发票(含源码)
  • Java排序算法之<希尔排序>
  • 7月27日星期日今日早报简报微语报早读
  • GitHub 趋势日报 (2025年07月25日)
  • Linux 系统网络配置及 IP 地址相关知识汇总
  • STM32 I2C通信完整教程:从协议原理到硬件实现
  • 一文快速了解Docker和命令详解
  • 模拟实现python的sklearn库中的Bunch类以及 load_iris 功能
  • 文件权限标记机制在知识安全共享中的应用实践
  • minio 对象存储
  • java的break能加标签,return可以加标签吗
  • 从一副蓝牙耳机里get倍思的“实用而美”
  • Python 程序设计讲义(23):循环结构——循环控制语句 break 与 continue
  • 背包DP之多重背包
  • 边缘提取算法结合深度学习的肺结节分割预测
  • 「日拱一码」040 机器学习-不同模型可解释方法
  • 【机器学习】第七章 特征工程
  • 【机器学习-3】 | 决策树与鸢尾花分类实践篇
  • 探索 Linux 调试利器:GDB 入门与实战指南
  • 在分布式的远程调用中proxy和stub角色区别
  • C++ 多线程 std::thread::get_id
  • 数独求解器与生成器(回溯算法实现)
  • Python|OpenCV-实现对颜色进行检测(22)
  • PandasAI连接LLM进行智能数据分析
  • qt常用控件-06
  • 【人工智能】【Python】各种评估指标,PR曲线,ROC曲线,过采样,欠采样(Scikit-Learn实践)
  • PAT 甲级题目讲解:1010《Radix》