数据结构和算法(八):队列

                                                                   队列

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列:先进先出 

队列的抽象数据类型

InitQueue(*Q): 初始化操作,建立一个空队列Q。 
DestroyQueue(*Q): 若队列Q存在,则销毁它。
ClearQueue(*Q): 将队列Q清空。 
QueueEmpty(Q): 若队列Q为空,返回true,否则返回false。
GetHead(Q, *e): 若队列Q存在且非空,用e返回队列Q的队头元素。
EnQueue(*Q, e): 若队列Q存在,插⼊新元素e到队列Q中并成为队尾元素。
DeQueue(*Q, *e): 删除队列Q中队头元素,并用e返回其值。
QueueLength(Q): 返回队列Q的元素个数

顺序存储

改进:

为了解决假溢出,就出现了循环队列

循环队列

也就是让front或rear指针不断加1,即时超出了地址范围,也会自动从头开始。我们可以采取取模运算处理:

(rear+1) % QueueSize

(front+1) % QueueSize

/***************************************
*  数据结构和算法--小甲鱼
*  队列循环队列
****************************************/

#include <stdio.h>
#include <stdlib.h>

typedef int  ElemType;
#define MAXSIZE  100
//定义一个循环队列
typedef struct
{
    ElemType *base; //用于存放内存分配的基地址
                    //也可以用数组来存放
    int front;
    int rear;
}  cycleQueue;

//初始化一个循环队列
int initQueue( cycleQueue *q)
{
    q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
    if(!q->base)
        return 0;
    q->front = q->rear = 0;
    return 1;
}
//入循环队列
 int InsertQueue(cycleQueue *q, ElemType e)
 {
     if((q->rear + 1) % MAXSIZE == q->front)
        return 0; //说明队列已经满了

     q->base[q->rear] = e;
     q->rear = (q->rear + 1) %MAXSIZE ;
     return 1;
 }

//出队列的操作
int DeleteQueue (cycleQueue *q , ElemType *e)
{
    if(q->front == q->rear)
        return 0; //说明队列为空,没有可以移出的东西

    *e = q->base[q->front]; //元素出队列
    q->front = (q->front + 1) % MAXSIZE;
    return 1;
}

int main()
{
    return 0;
}

 

链式存储

/***************************************
*  数据结构和算法--小甲鱼
*  队列的链式存储
****************************************/


#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;

typedef struct QNode
{
    ElemType data;
    struct QNode *next;
} QNode ,*QueuePtr;    //定义队列的结点

typedef struct
{
    QueuePtr front,rear;//指向队列的队尾 和 队头
}LinkQueue;            //定义队列的指针

//初始化一个队列
int initQueue (LinkQueue *q)
{
    q->front = q->rear = (QueuePtr) malloc (sizeof(QNode));
    if(!q->front)
        return -1;  //表示出错了
    q->front->next = NULL;   //头节点为空
}
//队尾入元素
InsertQueue(LinkQueue *p , ElemType *e)
{
    //首先是创建一个结点
    QueuePtr newP= (QueuePtr) malloc (sizeof(QNode));
    if(!newP)
        return -1;   //创建失败了

    //承接元素
    newP ->data = e;
    newP ->next = NULL;

    //开始链接

    p->rear->next = newP; //连接完毕
    p->rear = newP; //开始移动指针
}

//队头出元素
int DeleteQueue( LinkQueue *p , ElemType *e)
{
    QueuePtr newP;
    //首先是判断是否为空
    if(p->front == p->rear)
        return -1;       //为空没有元素
    newP = p->front->next;
    *e = newP->data;
    p->front->next = newP->next;

    if( p->rear == newP)
    {
        p->rear = p->front;
    }

    free(newP); // 释放结点

    return 1;  //结束
}
int DestroyQueue(LinkQueue *q)
{
    while( q->front ) {
        q->rear = q->front->next;
        free( q->front );
        q->front = q->rear;
       }
}

int main()
{
    ElemType e;
    LinkQueue q;

    initQueue(&q);
    printf("请输入一个字符串,以井号键结束输入:");
    scanf("%c", &e);

    while( e != '#' )
    {
        InsertQueue( &q, e );
        scanf("%c", &e);
    }

    printf("打印队列中的元素:");
    while( q.front != q.rear )
    {
        DeleteQueue( &q, &e );
        printf("%c", e);
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值