数据结构学习——链式队列的创建和使用

一、队列的介绍

        队列是一种常见的数据结构,它遵循先进先出(First-In-First-Out, FIFO)的原则,在队列的操作中入队从队列的尾部插入,出队的时候释放队列的头节点并且更新新的头节点。队列的存储方式主要有两种,分别是链式存储和顺序存储。每种存储方式都有其特点和适用场景。链式存储适合频繁进行插入和删除操作的队列,而顺序存储则适合频繁进行访问操作的队列。选择适当的存储方式要根据具体的应用需求和性能要求来决定。本篇主要介绍链式存储。

二、队列的创建以及初始化

        因为要用到链式存储的结构,因此需要定义结点结构体,以及队列的头尾指针。这里定义节点数据为int类型的data,结构体指针为next

typedef struct Node{
    int data;
    struct Node* next;
}Node;  //结点结构体定义

typedef struct{
    Node* front;    //头指针
    Node* rear;     //尾指针
}Queue;

        队列的初始化即分配一个节点内存,并且将头尾指针都指向这个空节点。

//链队列初始化
void Init_Queue(Queue* queue){
    //创建头节点
    queue->front = queue->rear = (Node*)malloc(sizeof(Node));
    if( !queue->front ){
    printf("内存分配失败\n");
    return;
    }
}

三、入队列

        入队列即在队尾插入一个新的节点,首先需要分配一块内存空间,将原来队尾指针指向新节点,并将新节点作为新的队尾。

//入队列
void Insert_Queue(Queue* queue,int value){
    Node* newCode;
    newCode = (Node*)malloc(sizeof(Node));
    if(newCode == NULL){
    printf("内存分配失败\n");
    return;
    }
    newCode->data = value;
    newCode->next = NULL;
    //判断是否是空队列
    if(queue->front == NULL){
        printf("该队列是空的\n");
        return;
    }
    //在尾部插入新节点
    queue->rear->next = newCode;
    //更新尾指针
    queue->rear = newCode;
}

四、出队列

        出队列的操作需要从队列的头进行,遵循先进先出的原理,因此需要将原来的头节点取出并释放,将下一个节点作为新的头节点。

void Delete_Queue(Queue* queue){
    if(queue->front == NULL){
        printf("该队列是空的\n");
        return;
    }
    /*queue->front为头指针,指向的头节点*/
    Node* pout = queue->front;
    //更新头指针
    queue->front = queue->front->next;
    //若队列中仅剩一个结点时,删除了该节点后
    //队列就为空,此时应该从新初始化
    if(queue->front == NULL)
    queue->rear = NULL;
    //释放删除结点的内存
    free(pout);
}

五、销毁队列

        销毁一个队列就是在出队列的基础上进行一个循环,跳出循环的条件就是链队列的头指针为空,并且逐个节点进行释放,最后重置链队列的头尾节点。

void Destroy_Queue(Queue* queue){
    Node* p = queue->front;
    while(p != NULL){
       Node* temp = p;
       p = p->next;
       free(temp);
    }
    printf("队列销毁成功!\n");
    //内存释放后指针重置,指向空
    queue->front = NULL;
    queue->rear = NULL;
}

六、遍历队列

        这里链队列的头指针指向了节点的头地址,因此要遍历打印队列需要从头指针的下一个节点开始。由于遍历链队列不需要对其进行修改,函数参数就不需要引用指针。

void Print_Queue(Queue queue){
   if(queue.front == NULL){
        printf("该队列是空的\n");
        return;
    } 
    Node* temp = queue.front->next;
    printf("该队列的内容为:\n");
    while(temp != NULL){
        printf("%d  ",temp->data);
        temp = temp->next;
    }
    printf("\n");
}

七、获取链队列的头

int GetHead_Queue(Queue queue){
    if(queue.front == NULL){
        printf("该队列是空的\n");
        return -1;
    }
    return  queue.front->next->data;
}

八、主函数及全部代码

        主函数:

void main(){
    //创建队列
    Queue queue;
    //队列初始化
    Init_Queue(&queue);
    //插入结点
    Insert_Queue(&queue,1);
    Insert_Queue(&queue,2);
    Insert_Queue(&queue,3);
    Print_Queue(queue);
    printf("该队列的头节点值为: %d \n",GetHead_Queue(queue));
    
    //删除结点
    Delete_Queue(&queue);
    Print_Queue(queue);
    
    //销毁队列
    Destroy_Queue(&queue);
    Print_Queue(queue);
}

全部代码:

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

typedef struct Node{
    int data;
    struct Node* next;
}Node;  //结点结构体定义

typedef struct{
    Node* front;    //头指针
    Node* rear;     //尾指针
}Queue;

//链队列初始化
void Init_Queue(Queue* queue){
    //创建头节点
    queue->front = queue->rear = (Node*)malloc(sizeof(Node));
    if( !queue->front ){
    printf("内存分配失败\n");
    return;
    }
}

//入队列
void Insert_Queue(Queue* queue,int value){
    Node* newCode;
    newCode = (Node*)malloc(sizeof(Node));
    if(newCode == NULL){
    printf("内存分配失败\n");
    return;
    }
    newCode->data = value;
    newCode->next = NULL;
    //判断是否是空队列
    if(queue->front == NULL){
        printf("该队列是空的\n");
        return;
    }
    //在尾部插入新节点
    queue->rear->next = newCode;
    //更新尾指针
    queue->rear = newCode;
}

void Delete_Queue(Queue* queue){
    if(queue->front == NULL){
        printf("该队列是空的\n");
        return;
    }
    /*queue->front为头指针,指向的头节点*/
    Node* pout = queue->front;
    //更新头指针
    queue->front = queue->front->next;
    //若队列中仅剩一个结点时,删除了该节点后
    //队列就为空,此时应该从新初始化
    if(queue->front == NULL)
    queue->rear = NULL;
    //释放删除结点的内存
    free(pout);
}

void Print_Queue(Queue queue){
   if(queue.front == NULL){
        printf("该队列是空的\n");
        return;
    } 
    Node* temp = queue.front->next;
    printf("该队列的内容为:\n");
    while(temp != NULL){
        printf("%d  ",temp->data);
        temp = temp->next;
    }
    printf("\n");
}

void Destroy_Queue(Queue* queue){
    Node* p = queue->front;
    while(p != NULL){
       Node* temp = p;
       p = p->next;
       free(temp);
    }
    printf("队列销毁成功!\n");
    //内存释放后指针重置,指向空
    queue->front = NULL;
    queue->rear = NULL;
}

int GetHead_Queue(Queue queue){
    if(queue.front == NULL){
        printf("该队列是空的\n");
        return -1;
    }
    return  queue.front->next->data;
}

void main(){
    //创建队列
    Queue queue;
    //队列初始化
    Init_Queue(&queue);
    //插入结点
    Insert_Queue(&queue,1);
    Insert_Queue(&queue,2);
    Insert_Queue(&queue,3);
    Print_Queue(queue);
    printf("该队列的头节点值为: %d \n",GetHead_Queue(queue));
    
    //删除结点
    Delete_Queue(&queue);
    Print_Queue(queue);
    
    //销毁队列
    Destroy_Queue(&queue);
    Print_Queue(queue);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值