数据结构与算法----队列

1队列的基本概念
队列(Queue):也是运算受限的线性表。是一种先进先出(First In First Out,简称FIFO)的线性表。只允许在表的一端进行插入,而在另一端进行删除。
队首(front):允许进行删除的一端称为队首。队尾(rear) :允许进行插入的一端称为队尾。
例如∶排队购物。操作系统中的作业排队。先进入队列的成员总是先离开队列。
 

顺序队列的基本操作

/*----------------------------------------------------------------
设立一个队首指针front ,一个队尾指针rear ,分别指向队首和队尾元素。

 ◆ 初始化:front=rear=0。
 ◆ 队列为空:front=rear。
 ◆ 队满:rear=MaxSize。
 ◆ 入队:将新元素插入rear所指的位置,然后rear加1。
 ◆ 出队:删去front所指的元素,然后加1并返回被删元素。
 ◆ 取队首元素:返回fornt指向的元素值
 -----------------------------------------------------------------*/

#include <stdio.h>
#include <assert.h>
#include <Windows.h>

#define MaxSize 10  //队列的最大容量

typedef int DataType;  //队列中元素类型
typedef struct Queue
{
    DataType Queue[MaxSize];
    int fornt;   //队头指针
    int rear;    //队尾指针
}SeqQueue;

//队列初始化,将队列初始化为空队列
void InitQueue(SeqQueue *SQ)
{
    SQ->fornt = SQ->rear = 0;  //把对头和队尾指针同时置0
 }

//判断队列为空

int IsEmpty(SeqQueue* SQ)
{
    if (SQ->fornt == SQ->rear)
    {
        return 1;
    }
    return 0;
}

//判断队列是否为满

int IsFull(SeqQueue* SQ)
{
    if (SQ->rear == MaxSize) 
    {
        return 1;
    }
    return 0;
}

//入队,将元素data插入到队列SQ中

void EnterQueue(SeqQueue* SQ,DataType data)
{
    if (IsFull(SQ))
    {
        printf("队列已满\n");
        return 0;
    }
    SQ->Queue[SQ->rear] = data;  //在队尾插入元素data
    SQ->rear = SQ->rear + 1;     //队尾指针后移一位
}

//出队,将队列中队头的元素data出队,出队后队头指针front后移一位
int DeleteQueue(SeqQueue* SQ,DataType* data)
{
    if (IsEmpty(SQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    *data = SQ->Queue[SQ->fornt];   //出队元素值
    SQ->fornt = (SQ->fornt)+1;      //队尾指针后移一位
    return 1;
}

//获取队首元素

int GetHead(SeqQueue* SQ,DataType* data)
{
    if (IsEmpty(SQ))
    {
        printf("队列为空!\n");
    }
    return *data = SQ->Queue[SQ->fornt];  
}

//清空队列

void ClearQueue(SeqQueue* SQ)
{
    SQ->fornt = SQ->rear = 0;
}

//打印队列中的与元素

void PrintQueue(SeqQueue* SQ)
{
    assert(SQ);    
    int i = SQ->fornt;
    while(i<SQ->rear)
    {
        printf("%-3d", SQ->Queue[i]);
        i++;
    }
    printf("\n");
}
int main()
{
    SeqQueue SQ;
    DataType data;
    //初始化队列
    InitQueue(&SQ);
    //入队
    EnterQueue(&SQ, 1);
    EnterQueue(&SQ, 2);
    EnterQueue(&SQ, 3);
    EnterQueue(&SQ, 4);
    EnterQueue(&SQ, 5);
    EnterQueue(&SQ, 6);
    EnterQueue(&SQ, 8);
    EnterQueue(&SQ, 10);
    EnterQueue(&SQ, 12);
    EnterQueue(&SQ, 15);
    EnterQueue(&SQ, 16);

    //打印队列中的元素
    printf("队列中的元素为:");
    PrintQueue(&SQ);
    printf("\n");
    //出队
    DeleteQueue(&SQ, &data);
    printf("出队元素为:%d\n", data);
    printf("\n");
    DeleteQueue(&SQ, &data);
    printf("出队元素为:%d\n", data);
    printf("\n");
    printf("队列中的元素为:");
    PrintQueue(&SQ);
    printf("\n");
    //获取队首元素
    data = GetHead(&SQ, &data);
    printf("队首元素为:%d\n", data);
    printf("#元素16入队#\n");
    //元素16入队
    EnterQueue(&SQ, 16);
    printf("队列中的元素为:");
    PrintQueue(&SQ);
    printf("\n");
    system("pause");
    return 0;
}
循环队列的基本操作

/*----------------------------------------------------------------
设立一个队首指针front ,一个队尾指针rear ,分别指向队首和队尾元素。

◆ 初始化:front=rear=0。
◆ 队列为空:front=rear。
◆ 队满:(rear + 1) % MaxSize == fornt
◆ 入队:将新元素插入rear所指的位置,然后rear加1。
◆ 出队:删去front所指的元素,然后加1并返回被删元素。
◆ 取队首元素:返回fornt指向的元素值
-----------------------------------------------------------------*/

#include<stdio.h>
#include<Windows.h>
#include<assert.h>

#define MaxSize 10
typedef int DataType;
typedef struct SeqQueue
{
    DataType Queue[MaxSize];
    int fornt;
    int rear;
}SeqCirQueue;

//队列初始化

void InitSeqCirQueue(SeqCirQueue* SCQ)
{
    SCQ->fornt = SCQ->rear = 0;
}

//判断队列是否为空
int IsEmpty(SeqCirQueue* SCQ)
{
    if (SCQ->fornt == SCQ->rear)
    {
        return 1;
    }
    return 0;
}

//判断队列是否为满
int IsFull(SeqCirQueue* SCQ)
{
    //尾指针+1追上队头指针,标志队列已经满了
    if ((SCQ->rear + 1) % MaxSize == SCQ->fornt)
    {
        return 1;
    }
    return 0;
}

//入队操作
int EnterSeqCirQueue(SeqCirQueue* SCQ, DataType data)
{
    if (IsFull(SCQ))
    {
        printf("队列已满,不能入队!\n");
        return 0;
    }
    SCQ->Queue[SCQ->rear] = data;
    SCQ->rear = (SCQ->rear + 1) % MaxSize;   //重新设置队尾指针
}


//出队操作
int DeleteSeqCirQueue(SeqCirQueue* SCQ,DataType* data)
{
    if (IsEmpty(SCQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    *data = SCQ->Queue[SCQ->fornt];
    SCQ->fornt = (SCQ->fornt + 1) % MaxSize;  //重新设置队头指针
}

//取队首元素
int GetHead(SeqCirQueue* SCQ,DataType* data)
{
    if (IsEmpty(SCQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    *data = SCQ->Queue[SCQ->fornt];
    return *data;
}

//清空队列
void ClearSeqCirQueue(SeqCirQueue* SCQ)
{
    SCQ->fornt = SCQ->rear = 0;
}

//打印队列元素
void PrintSeqCirQueue(SeqCirQueue* SCQ)
{
    assert(SCQ);   //断言SCQ不为空
    int i = SCQ->fornt;
    if (SCQ->fornt < SCQ->rear)
    {
        for (; i < SCQ->rear; i++)
        {
            printf("%-3d", SCQ->Queue[i]);
        }
    }
    else
    {
        for (i; i <SCQ->rear + MaxSize; i++)
        {
            printf("%-3d", SCQ->Queue[i]);
        }
    }
    printf("\n");
}

int main()
{
    SeqCirQueue SCQ;
    DataType data;
    //初始化队列
    InitSeqCirQueue(&SCQ);
    //入队
    EnterSeqCirQueue(&SCQ, 1);
    EnterSeqCirQueue(&SCQ, 2);
    EnterSeqCirQueue(&SCQ, 4);
    EnterSeqCirQueue(&SCQ, 6);
    EnterSeqCirQueue(&SCQ, 8);
    EnterSeqCirQueue(&SCQ, 9);
    EnterSeqCirQueue(&SCQ, 10);
    EnterSeqCirQueue(&SCQ, 12);
    EnterSeqCirQueue(&SCQ, 13);
    printf("队列中元素为:\n");
    //打印队列中元素
    PrintSeqCirQueue(&SCQ);
    EnterSeqCirQueue(&SCQ, 15);
    //出队
    DeleteSeqCirQueue(&SCQ, &data);
    printf("出队元素为:%d\n", data);
    printf("\n");
    printf("队列中元素为:\n");
    PrintSeqCirQueue(&SCQ);
    printf("15入队:\n");
    EnterSeqCirQueue(&SCQ, 15);
    printf("队列中元素为:\n");
    PrintSeqCirQueue(&SCQ);
    system("pause");
    return 0;
}
*链式队列的基本操作

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

typedef int DataType;
typedef struct Node
{
    DataType _data;
    struct Node* _next;
}LinkQueueNode;

typedef struct
{
    LinkQueueNode* front;
    LinkQueueNode* rear;
}LinkQueue;

//初始化队列
void InitLinkQueue(LinkQueue* LQ)
{
    //创建一个头结点
    LinkQueueNode* pHead = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    assert(pHead);
    LQ->front = LQ->rear = pHead; //队头和队尾指向头结点
    LQ->front->_next = NULL;
}

//判断队列是否为空

int IsEmpty(LinkQueue* LQ)
{
    if (LQ->front->_next == NULL)
    {
        return 1;
    }
    return 0;
}

//入队操作

void EnterLinkQueue(LinkQueue* LQ, DataType data)
{
    //创建一个新结点
    LinkQueueNode* pNewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
    assert(pNewNode);
    pNewNode->_data = data;  //将数据元素赋值给结点的数据域
    pNewNode->_next = NULL;  //将结点的指针域置空
    LQ->rear->_next = pNewNode;   //将原来队列的队尾指针指向新结点
    LQ->rear = pNewNode;      //将队尾指针指向新结点
}

//出队操作

void DeleteLinkQueue(LinkQueue* LQ,DataType* data)
{
    if (IsEmpty(LQ))
    {
        printf("队列为空!\n");
        return;
    }
    //pDel指向队头元素,由于队头指针front指向头结点,所以pDel指向头结点的下一个结点
    LinkQueueNode* pDel = LQ->front->_next;  
    *data = pDel->_data;   //将要出队的元素赋给data
    LQ->front->_next = pDel->_next;  //使指向头结点的指针指向pDel的下一个结点
    //如果队列中只有一个元素,将队列置空
    if (LQ->rear = pDel)   
    {
        LQ->rear = LQ->front;
    }
    free(pDel);   //释放pDel指向的空间
}

//取队头元素

int GetHead(LinkQueue* LQ, DataType* data)
{
    if (IsEmpty(LQ))
    {
        printf("队列为空!\n");
        return 0;
    }
    LinkQueueNode* pCur;
    pCur = LQ->front->_next;  //pCur指向队列的第一个元素,即头结点的下一个结点
    *data = pCur->_data;      //将队头元素值赋给data
    return *data;             //返回队头元素值
}

//清空队列

void ClearQueue(LinkQueue* LQ)
{
    while (LQ->front != NULL)
    {
        LQ->rear = LQ->front->_next;  //队尾指针指向队头指针的下一个结点
        free(LQ->front);              //释放队头指针指向的结点
        LQ->front = LQ->rear;         //队头指针指向队尾指针
    }
}

//打印队列中的元素

void PrintLinkQueue(LinkQueue* LQ)
{
    assert(LQ);
    LinkQueueNode * pCur;
    pCur = LQ->front->_next;
    while (pCur)
    {
        printf("%-3d", pCur->_data);
        pCur = pCur->_next;
    }
    printf("\n");
}
int main()
{
    LinkQueue LQ; 
    DataType data;
    //初始化队列
    InitLinkQueue(&LQ);
    //入队
    EnterLinkQueue(&LQ, 1); 
    EnterLinkQueue(&LQ, 2);
    EnterLinkQueue(&LQ, 3);
    EnterLinkQueue(&LQ, 4);
    EnterLinkQueue(&LQ, 5);
    EnterLinkQueue(&LQ, 6);
    EnterLinkQueue(&LQ, 7);
    EnterLinkQueue(&LQ, 8);
    printf("队列中的元素为:");
    //打印队列中元素
    PrintLinkQueue(&LQ);
    printf("\n");
    //取队头元素
    data = GetHead(&LQ, &data);
    printf("队头元素为:%d\n", data);
    printf("\n");
    //出队
    DeleteLinkQueue(&LQ, &data);
    printf("出队的元素为:%d\n", data);
    printf("\n");
    printf("队列中的元素为:");
    PrintLinkQueue(&LQ);
    printf("\n");
    data = GetHead(&LQ, &data);
    printf("队头元素为:%d\n", data);
    printf("\n");
    ClearQueue(&LQ);
    system("pause");
    return 0;
}

————————————————
版权声明:本文为CSDN博主「LiuBo_01」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LiuBo_01/article/details/80412290

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值