C语言队列操作笔记

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

#define MAXSIZE 8                                           // 最大队列长度   
#define OVERFLOW -2                                         // 失败
#define OK 1                                                // 成功   
                    
typedef int QElemType;                                      // 动态分配空间类型   
typedef int Stutus;                                         // 函数类型
// 定义顺序队列节点                             
typedef struct                              
{                               
    QElemType *base;                                        // 初始化动态分配空间
    int front;                                              // 头下标
    int rear;                                               // 尾下标
} SqQueue; 
/* -------------------------------------------------------------------------- */
// 定义链队列节点
typedef struct QNode
{
    QElemType data;
    struct QNode *next;
}QNode, *QueuePtr;
// 定义头尾指针
typedef struct
{
    QueuePtr front2;
    QueuePtr rear2;
} LinkQueue;


/* 预定义函数 */             
Stutus InitSqQueue(SqQueue *Q);                             // 初始化队列
Stutus SqQueueLength(SqQueue Q);                            // 获取队列长度
Stutus EnQueue(SqQueue *Q, QElemType e);                    // 循环队列入队
Stutus DeQueue(SqQueue *Q, QElemType *e);                   // 循环队列出队 
QElemType GetHead(SqQueue Q);                               // 循环队列获取头元素  
void print(SqQueue Q);                                      // 遍历队列   
/* --------------------------------------------------------------------------- */
Stutus InitQueue(LinkQueue *Q);                             // 初始化链队列
Stutus DestroyQueue(LinkQueue *Q);                          // 销毁链队列
Stutus EnLinkQueue(LinkQueue *Q, QElemType e);              // 链队列入队
Stutus DeLinkQueue(LinkQueue *Q, QElemType *e);             // 链队列出队
Stutus GetQueueHead(LinkQueue Q, QElemType *e);             // 链队列获取头元素  
void Linkprint(LinkQueue Q);                     
/* 预定义函数end */    

int main(int argc, char const *argv[])                  
{      
/* ------------------------------------循环队列-------------------------------- */            
    SqQueue Q;                                              // 定义队列变量
    int arr[] = {1, 3, 5, 7, 9, 2, 4, 6}; 
    int arr_len = sizeof(arr)/sizeof(int);                  // 设置长度 
    int e, flag;  
    /* 初始化队列 */
    InitSqQueue(&Q);
    /* 获取队列长度 */        
    printf("当前队列长度Qlen = %d\n", SqQueueLength(Q));
    
    /* 循环队列入队 */
    printf("循环队列入队:");
    for (int i = 0; i < arr_len; i++)
    {
        EnQueue(&Q, arr[i]);
    }
    print(Q);
    printf("当前队列长度Qlen = %d\n", SqQueueLength(Q));

    /* 循环队列出队 */
    DeQueue(&Q, &e);
    printf("当前队列出队元素e = %d\n", e);
    printf("循环队列元素:");
    print(Q);
    printf("当前队列长度Qlen = %d\n", SqQueueLength(Q));
    printf("---------------------------------------------------------\n");
/* ------------------------------------链队列------------------------------------- */
    LinkQueue LQ;
    /* 初始化链队列 */
    flag = InitQueue(&LQ); 
    if (flag == 1) printf("初始化链队列!!!\n");

    /* 链队列入队 */
    printf("链队列入队:");
    for (int i = 0; i < arr_len; i++)
    {
        EnLinkQueue(&LQ, arr[i]); 
    }
    Linkprint(LQ); 

    /* 链队列获取头元素 */
    GetQueueHead(LQ, &e);
    printf("链队列获取头元素:%d\n", e);

    /* 链队列出队 */
    DeLinkQueue(&LQ, &e);
    printf("链队列出队元素:%d\n", e);
    Linkprint(LQ); 
    
    // DestroyQueue(&LQ); // 销毁队列                 
    return 0;
}

/* 初始化队列 */
Stutus InitSqQueue(SqQueue *Q)
{
    Q->base = malloc(MAXSIZE * sizeof(QElemType));          // 分配存储空间
    if (!Q->base) exit(OVERFLOW);                           // 判断是否分配成功
    Q->front = Q->rear = 0;                                 // 头尾指针为0,队列空
    return OK;    
}

/* 获取队列长度 */
Stutus SqQueueLength(SqQueue Q)
{
    return (Q.rear - Q.front + MAXSIZE % MAXSIZE);          // 头-尾+最大值取余最大值
}

/* 循环队列入队 */
Stutus EnQueue(SqQueue *Q, QElemType e)
{
    if ((Q->rear+1) % MAXSIZE == Q->front) return OVERFLOW; // 队满,入队失败
    Q->base[Q->rear] = e;                                   // 存入值
    Q->rear = (int)(Q->rear+1) % MAXSIZE;                   // 尾下标+1,当尾下标是最大值时,最大值+1取余最大值实现循环插入
    return OK;
}

/* 循环队列出队 */
Stutus DeQueue(SqQueue *Q, QElemType *e)
{
    if (Q->rear == Q->front) return OVERFLOW;               // 对空,入队失败
    *e = Q->base[Q->front];                                 // 获取对头元素
    Q->front = (Q->front+1) % MAXSIZE;                      // 对头+1
    return OK;
}

/* 循环队列获取头元素 */
QElemType GetHead(SqQueue Q)
{
    if (Q.front != Q.rear) return Q.base[Q.front];          // 队列非空直接获取
}                                  

void print(SqQueue Q)
{ 
    for (int i = Q.front; i < Q.rear; i++)
    {
        printf("%d\t", Q.base[i]);
    }
    printf("\n");
}
/* ------------------------------------链队列函数-------------------------------------------- */
/* 初始化链队列 */
Stutus InitQueue(LinkQueue *Q)
{
    Q->front2 = Q->rear2 = (QueuePtr)malloc(sizeof(QNode));         // 创建存储空间,头尾指针同时指向
    if (!Q->front2) exit(OVERFLOW);                                 // 分配失败
    Q->front2->next = NULL;                                         // 头节点后置置空
    return OK;
}      
/* 销毁链队列:从头节点开始依次删除所有节点 */      
Stutus DestroyQueue(LinkQueue *Q)
{
    QNode *temp;                                                    // 定义临时指针, 记录删除节点后继地址
    while (Q->front2)                                               /* 循环头指针至空 */
    {
        temp = Q->front2->next;                                     // 记录头节点后继地址
        free(Q->front2);                                            // 释放头节点
        Q->front2 = temp;                                           // 后一个节点变成头节点
    }
    return OK;
}         
/* 链队列插入操作:尾节点插入新节点 */
Stutus EnLinkQueue(LinkQueue *Q, QElemType e)
{
    QNode *temp;                                                    // 创建临时指针
    temp = (QueuePtr)malloc(sizeof(QNode));                         // 创建新节点
    if (!temp) exit(OVERFLOW);                                      // 判断是否创建成功
    temp->data = e;                                                 // 添加元素
    temp->next = NULL;                                              // 置空后继节点
    Q->rear2->next = temp;                                          // 原末尾节点后继指向新节点
    Q->rear2 = temp;                                                // 尾指针指向新尾节点
    return OK;
} 
/* 链队列出队操作:删除首元节点,头节点后继指向下一节点,
 *   特殊情况:只两个节点时,删除后要将头尾指针指向同一节点。
 */
Stutus DeLinkQueue(LinkQueue *Q, QElemType *e)
{
    QNode *temp;                                                    // 创建临时指针
    temp = Q->front2->next;                                         // 记录节点地址
    *e = temp->data;                                                // 记录删除节点数据,QElemType为int需要转类型
    Q->front2->next = temp->next;                                   // 修改头节点后继指向下下节点
    if (Q->front2->next == Q->rear2) Q->rear2 =  Q->front2;         // 头尾指针指向头节点
    free(temp);                                                     // 释放
    return OK;
}
/* 链队列获取头元素 */
Stutus GetQueueHead(LinkQueue Q, QElemType *e)                                  
{
    if (Q.front2 == Q.rear2) return OVERFLOW;                       // 判断是否为空队
    *e = Q.front2->next->data;                                      // 获取头元素
    return OK;
}    

/* 遍历链队列 */
void Linkprint(LinkQueue Q)
{
    QNode *temp = Q.front2->next;                                   // 创建指针指向首元节点
    while (temp != NULL)                                            // 循环直至空
    {
        printf("%d\t", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZiWie丶ZHANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值