博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构 - 链队列的实行(C语言)
阅读量:5140 次
发布时间:2019-06-13

本文共 4878 字,大约阅读时间需要 16 分钟。

数据结构-链队列的实现

1 链队列的定义

队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,

我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端结点,如下图所示。

img

空队列时,front和rear都指向头结点,如下图所示。

img

链队列的结构为:

typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */typedef struct QNode    /* 结点结构 */{   QElemType data;   struct QNode *next;}QNode,*QueuePtr;typedef struct          /* 队列的链表结构 */{   QueuePtr front,rear; /* 队头、队尾指针 */}LinkQueue;

2 入队操作

人队操作时,其实就是在链表尾部插入结点,如下图所示。

img

代码如下:

/* 插入元素e为Q的新的队尾元素 */Status EnQueue(LinkQueue *Q, QElemType e){    QueuePtr s = (QueuePtr)malloc(sizeof(QNode));    if (!s) /* 存储分配失败 */        exit(OVERFLOW);    s->data = e;    s->next = NULL;    Q->rear->next = s;  /* 把拥有元素e的新结点s赋值给原队尾结点的后继,见图中① */    Q->rear = s;        /* 把当前的s设置为队尾结点,rear指向s,见图中② */    return TRUE;}

3 出队操作

出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点,

若链表除头结点外只剩一个元素时,则需将rear指向头结点,如下图所示。

img

代码如下:

/* 若队列不空,删除Q的队头元素,用e返回其值,并返回TRUE,否则返回FALSE */Status DeQueue(LinkQueue *Q, QElemType *e){    QueuePtr p;    if (Q->front == Q->rear)        return FALSE;    p = Q->front->next;     /* 将欲删除的队头结点暂存给p,见图中① */    *e = p->data;               /* 将欲删除的队头结点的值赋值给e */    Q->front->next = p->next;/* 将原队头结点的后继p->next赋值给头结点后继,见图中② */    if (Q->rear == p)       /* 若队头就是队尾,则删除后将rear指向头结点,见图中③ */        Q->rear = Q->front;    free(p);    return TRUE;}

4 完整实现

#include "stdafx.h"       #include "stdlib.h"   #include "math.h"  //定义了OVERFLOW#define TRUE 1#define FALSE 0#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int Status;typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */typedef struct QNode    /* 结点结构 */{    QElemType data;    struct QNode *next;}QNode, *QueuePtr;typedef struct          /* 队列的链表结构 */{    QueuePtr front, rear; /* 队头、队尾指针 */}LinkQueue;Status visit(QElemType c){    printf("%d ", c);    return TRUE;}/* 构造一个空队列Q */Status InitQueue(LinkQueue *Q){    Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));    if (!Q->front)        exit(OVERFLOW);    Q->front->next = NULL;    return TRUE;}/* 销毁队列Q */Status DestroyQueue(LinkQueue *Q){    while (Q->front)    {        Q->rear = Q->front->next;        free(Q->front);        Q->front = Q->rear;    }    return TRUE;}/* 将Q清为空队列 */Status ClearQueue(LinkQueue *Q){    QueuePtr p, q;    Q->rear = Q->front;    p = Q->front->next;    Q->front->next = NULL;    while (p)    {        q = p;        p = p->next;        free(q);    }    return TRUE;}/* 若Q为空队列,则返回TRUE,否则返回FALSE */Status QueueEmpty(LinkQueue Q){    if (Q.front == Q.rear)        return TRUE;    else        return FALSE;}/* 求队列的长度 */int QueueLength(LinkQueue Q){    int i = 0;    QueuePtr p;    p = Q.front;    while (Q.rear != p)    {        i++;        p = p->next;    }    return i;}/* 若队列不空,则用e返回Q的队头元素,并返回TRUE,否则返回FALSE */Status GetHead(LinkQueue Q, QElemType *e){    QueuePtr p;    if (Q.front == Q.rear)        return FALSE;    p = Q.front->next;    *e = p->data;    return TRUE;}/* 插入元素e为Q的新的队尾元素 */Status EnQueue(LinkQueue *Q, QElemType e){    QueuePtr s = (QueuePtr)malloc(sizeof(QNode));    if (!s) /* 存储分配失败 */        exit(OVERFLOW);    s->data = e;    s->next = NULL;    Q->rear->next = s;  /* 把拥有元素e的新结点s赋值给原队尾结点的后继,见图中① */    Q->rear = s;        /* 把当前的s设置为队尾结点,rear指向s,见图中② */    return TRUE;}/* 若队列不空,删除Q的队头元素,用e返回其值,并返回TRUE,否则返回FALSE */Status DeQueue(LinkQueue *Q, QElemType *e){    QueuePtr p;    if (Q->front == Q->rear)        return FALSE;    p = Q->front->next;     /* 将欲删除的队头结点暂存给p,见图中① */    *e = p->data;               /* 将欲删除的队头结点的值赋值给e */    Q->front->next = p->next;/* 将原队头结点的后继p->next赋值给头结点后继,见图中② */    if (Q->rear == p)       /* 若队头就是队尾,则删除后将rear指向头结点,见图中③ */        Q->rear = Q->front;    free(p);    return TRUE;}/* 从队头到队尾依次对队列Q中每个元素输出 */Status QueueTraverse(LinkQueue Q){    QueuePtr p;    p = Q.front->next;    while (p)    {        visit(p->data);        p = p->next;    }    printf("\n");    return TRUE;}int main(){    int i;    QElemType d;    LinkQueue q;    i = InitQueue(&q);    if (i)        printf("成功地构造了一个空队列!\n");    printf("是否空队列?%d(1:空 0:否)  ", QueueEmpty(q));    printf("队列的长度为%d\n", QueueLength(q));    EnQueue(&q, -5);    EnQueue(&q, 5);    EnQueue(&q, 10);    printf("插入3个元素(-5,5,10)后,队列的长度为%d\n", QueueLength(q));    printf("是否空队列?%d(1:空 0:否)  ", QueueEmpty(q));    printf("队列的元素依次为:");    QueueTraverse(q);    i = GetHead(q, &d);    if (i == TRUE)        printf("队头元素是:%d\n", d);    DeQueue(&q, &d);    printf("删除了队头元素%d\n", d);    i = GetHead(q, &d);    if (i == TRUE)        printf("新的队头元素是:%d\n", d);    ClearQueue(&q);    printf("清空队列后,q.front=%u q.rear=%u q.front->next=%u\n", q.front, q.rear, q.front->next);    DestroyQueue(&q);    printf("销毁队列后,q.front=%u q.rear=%u\n", q.front, q.rear);    return 0;}/*输出结果:成功地构造了一个空队列!是否空队列?1(1:空 0:否)  队列的长度为0插入3个元素(-5,5,10)后,队列的长度为3是否空队列?0(1:空 0:否)  队列的元素依次为:-5 5 10队头元素是:-5删除了队头元素-5新的队头元素是:5清空队列后,q.front=23238400 q.rear=23238400 q.front->next=0销毁队列后,q.front=0 q.rear=0*/

转载于:https://www.cnblogs.com/linuxAndMcu/p/10327836.html

你可能感兴趣的文章
web页面实现指定区域打印功能
查看>>
使用PHP拆分中文字符串的方法(收藏) 小节
查看>>
android系统权限的管理
查看>>
win10每次开机都显示“你的硬件设置已更改,请重启电脑……”的解决办法
查看>>
因Window服务器自动更新并重启导致WebSphere服务停止服务故障一例
查看>>
如何开启safari的调试
查看>>
js深拷贝和浅拷贝
查看>>
node.js 基础学习笔记1
查看>>
如何在linux系统中设置静态ip地址
查看>>
二分查找法,折半查找原理
查看>>
DP简单问题联系--最长递增子序列+最长公共子序列等
查看>>
2017-4-18 Zabbix server的安装以及ansible批量部署zabbix agent的工作笔记
查看>>
1066. Root of AVL Tree (25)
查看>>
maven的pom.xml用<exclusion>解决版本问题
查看>>
JSP—page指令
查看>>
NOIP的基本模板合集(2)
查看>>
openscales2.2 的初始缩放等级
查看>>
hdu 4310 Hero
查看>>
mac中使用vi修改二进制文件
查看>>
css3 box-sizing属性
查看>>