数据结构 队列的操作

Posted 天码丶行满

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 队列的操作相关的知识,希望对你有一定的参考价值。

队列:一种先进先出的数据结构,一端插入一端删除。

存储方式:分为顺序队列、链式队列

 

队列顺序存储:

头文件:

#pragma once


#include<stdlib.h>

//顺序队列
struct SQueue{
    void *data[1024]; //保存数据的内存
    int size;
};

typedef void *SeqQueue;

#ifdef __cplusplus
extern "C"{
#endif

    //初始化
    SeqQueue Init_SeqQueue();
    //入队
    void Push_SeqQueue(SeqQueue queue, void *data);
    //出队
    void Pop_SeqQueue(SeqQueue queue);
    //获得队头元素
    void *Front_SeqQueue(SeqQueue queue);
    //获得队尾元素
    void *Back_SeqQueue(SeqQueue queue);
    //获得队列大小
    int Size_SeqQueue(SeqQueue queue);
    //销毁队列
    void Destroy_SeqQueue(SeqQueue queue);

#ifdef __cplusplus
}
#endif

 

头文件实现:

#include"SeqQueue.h"


//初始化
SeqQueue Init_SeqQueue(){

    struct SQueue *queue = malloc(sizeof(struct SQueue));
    if (NULL == queue){
        return NULL;
    }
    queue->size = 0;
    for (int i = 0; i < 1024; i ++){
        queue->data[i] = NULL;
    }

    return queue;
}
//入队
void Push_SeqQueue(SeqQueue queue, void *data){

    if (NULL == queue){
        return;
    }

    if (NULL == data){
        return;
    }

    struct SQueue *q = (struct SQueue *)queue;

    if (q->size == 1024){
        return;
    }


    //移动元素,把0号位置空出来
    for (int i = q->size - 1; i >= 0; i--){
        q->data[i + 1] = q->data[i];
    }

    q->data[0] = data;
    q->size++;

}
//出队
void Pop_SeqQueue(SeqQueue queue){
    if (NULL == queue){
        return;
    }

    struct SQueue *q = (struct SQueue *)queue;
    if (q->size == 0){
        return;
    }
    q->size--;

}
//获得队头元素
void *Front_SeqQueue(SeqQueue queue){
    if (NULL == queue){
        return NULL;
    }

    struct SQueue *q = (struct SQueue *)queue;
    return q->data[q->size - 1];
}
//获得队尾元素
void *Back_SeqQueue(SeqQueue queue){
    if (NULL == queue){
        return NULL;
    }

    struct SQueue *q = (struct SQueue *)queue;
    return q->data[0];
}
//获得队列大小
int Size_SeqQueue(SeqQueue queue){
    if (NULL == queue){
        return -1;
    }

    struct SQueue *q = (struct SQueue *)queue;
    return q->size;
}
//销毁队列
void Destroy_SeqQueue(SeqQueue queue){
    if (NULL == queue){
        return;
    }
    free(queue);
    queue = NULL;
}

 

 

测试文件:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"SeqQueue.h"

struct Person{
    char name[64];
    int age;
};

void test(){

    //创建数据
    struct Person p1 = { "aaa", 10 };
    struct Person p2 = { "bbb", 20 };
    struct Person p3 = { "ccc", 30 };
    struct Person p4 = { "ddd", 40 };
    struct Person p5 = { "eee", 50 };

    //初始化队列
    SeqQueue queue = Init_SeqQueue();
    //数据入队列
    Push_SeqQueue(queue, &p1);
    Push_SeqQueue(queue, &p2);
    Push_SeqQueue(queue, &p3);
    Push_SeqQueue(queue, &p4);
    Push_SeqQueue(queue, &p5);

    //输出队头 队尾元素
    struct Person *front =  (struct Person *)Front_SeqQueue(queue);
    struct Person *back = (struct Person *)Back_SeqQueue(queue);
    printf("队头元素: Name:%s Age:%d\n",front->name,front->age);
    printf("队尾元素: Name:%s Age:%d\n", back->name, back->age);
    printf("-----------------------------\n");

    //输出队列中元素
    while (Size_SeqQueue(queue) > 0){
        //获得对头元素
        front = (struct Person *)Front_SeqQueue(queue);
        printf("Name:%s Age:%d\n", front->name, front->age);
        //弹出队头元素
        Pop_SeqQueue(queue);
    }

    //打印大小
    printf("Size:%d\n",Size_SeqQueue(queue));

    //销毁队列
    Destroy_SeqQueue(queue);

}

int main(){

    test();

    system("pause");
    return EXIT_SUCCESS;
}

 

队列的链式存储:

 

头文件:

#pragma once

#include"LinkList.h"

struct QueueNode{
	struct LinkNode node;
};

#ifdef __cplusplus
extern "C"{
#endif

	//初始化链式队列
	void *Init_LinkQueue();
	//入队列
	void Push_LinkQueue(void *queue, void *data);
	//出队
	void Pop_LinkQueue(void *queue);
	//大小
	int Size_LinkQueue(void *queue);
	//获得队头元素
	void *Front_LinkQueue(void *queue);
	//获得队尾元素
	void *Back_LinkQueue(void *queue);
	//销毁队列
	void Destroy_LinkQueue(void *queue);


#ifdef __cplusplus
}
#endif

 

#pragma once

#include<stdlib.h>

//链表小节点

//目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
struct LinkNode{
    struct LinkNode *next;
};

//链表结构体
struct LList{
    struct LinkNode header;
    int size;
};

typedef void *LinkList;

//初始化
LinkList Init_LinkList();

//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos);
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *));
//根据位置获得值
void *Get_LinkList(LinkList list,int pos);
int Size_LinkList(LinkList list);


//销毁
void Destroy_LinkList(LinkList list);

 

 

 

头文件实现:

#include"LinkQueue.h"

//初始化链式队列
void *Init_LinkQueue(){
    return Init_LinkList();
}
//入队列
void Push_LinkQueue(void *queue, void *data){
    Insert_LinkList(queue, 0, data);
}
//出队
void Pop_LinkQueue(void *queue){
    RemoveByPos_LinkList(queue, Size_LinkList(queue) - 1);
}
//大小
int Size_LinkQueue(void *queue){
    return Size_LinkList(queue);
}
//获得队头元素
void *Front_LinkQueue(void *queue){
    return Get_LinkList(queue , Size_LinkList(queue) - 1);
}
//获得队尾元素
void *Back_LinkQueue(void *queue){
    return Get_LinkList(queue, 0);
}
//销毁队列
void Destroy_LinkQueue(void *queue){
    Destroy_LinkList(queue);
}
#include"LinkList.h"


//初始化
LinkList Init_LinkList(){

    struct LList *list = malloc(sizeof(struct LList));
    if (NULL == list){
        return NULL;
    }
    list->header.next = NULL;
    list->size = 0;

    return list;
}
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){
    
    if (NULL == list){
        return;
    }

    if (NULL == data){
        return;
    }
    
    struct LList *llist = (struct LList *)list;

    if (pos < 0 || pos >llist->size){
        pos = llist->size;
    }

    //查找pos位置前一个位置的节点
    struct LinkNode *pCurrent = &(llist->header);
    for (int i = 0; i < pos;i ++){
        pCurrent = pCurrent->next;
    }

    //将新节点插入到链表
    data->next = pCurrent->next;
    pCurrent->next = data;

    llist->size++;
}

//位置删除
void RemoveByPos_LinkList(LinkList list, int pos){

    if (NULL ==list){
        return;
    }

    struct LList *llist = (struct LList *)list;


    if (llist->size == 0){
        return;
    }

    if (pos < 0 || pos > llist->size - 1){
        return;
    }


    //找到pos位置的前一个节点
    struct LinkNode *pCurrent = &(llist->header);
    for (int i = 0; i < pos; i ++){
        pCurrent = pCurrent->next;
    }

    //缓存下待删除节点
    struct LinkNode *pDel = pCurrent->next;
    //重新建立待删除的节点前驱后继节点关系
    pCurrent->next = pDel->next;

    llist->size--;
}


//根据位置获得值
void *Get_LinkList(LinkList list, int pos){
    if (NULL == list){
        return NULL;
    }

    struct LList *llist = (struct LList *)list;
    if (pos < 0 || pos > llist->size - 1){
        return NULL;
    }

    //辅助指针变量
    struct LinkNode *pCurrent = &(llist->header);
    for (int i = 0; i < pos; i++){
        pCurrent = pCurrent->next;
    }


    return pCurrent->next;
}

int Size_LinkList(LinkList list){
    if (NULL == list){
        return -1;
    }

    struct LList *llist = (struct LList *)list;
    return llist->size;
}


//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
    if (NULL == list){
        return;
    }

    struct LList *llist = (struct LList *)list;
    //辅助指针变量
    struct LinkNode *pCurrent = llist->header.next;
    while (pCurrent != NULL){
        foreach(pCurrent);
        pCurrent = pCurrent->next;
    }
}

//销毁
void Destroy_LinkList(LinkList list){
    if (NULL == list){
        return;
    }

    free(list);
    list = NULL;
}

 

测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkQueue.h"

struct Person{
    struct QueueNode node;
    char name[64];
    int age;
};

void test(){

    //创建测试数据
    struct Person p1 = { NULL ,"aaa", 10 };
    struct Person p2 = { NULL ,"bbb", 20 };
    struct Person p3 = { NULL ,"ccc", 30 };
    struct Person p4 = { NULL ,"ddd", 40 };
    struct Person p5 = { NULL ,"eee", 50 };
    
    void *queue = Init_LinkQueue();

    //数据入队
    Push_LinkQueue(queue, &p1);
    Push_LinkQueue(queue, &p2);
    Push_LinkQueue(queue, &p3);
    Push_LinkQueue(queue, &p4);
    Push_LinkQueue(queue, &p5);

    struct Person *front = (struct Person *)Front_LinkQueue(queue);
    struct Person *back = (struct Person *)Back_LinkQueue(queue);
    printf("Front: Name:%s Age:%d\n",front->name,front->age);
    printf("Back: Name:%s Age:%d\n", back->name, back->age);
    printf("-------------------------------\n");
    //输出队列中的元素
    while (Size_LinkQueue(queue) > 0){
        
        front = (struct Person *)Front_LinkQueue(queue);
        printf("Name:%s Age:%d\n", front->name, front->age);
        //弹出队头元素
        Pop_LinkQueue(queue);
    }

    //销毁队列
    Destroy_LinkQueue(queue);

}

int main(){

    test();

    system("pause");
    return EXIT_SUCCESS;
}

 

以上是关于数据结构 队列的操作的主要内容,如果未能解决你的问题,请参考以下文章

perl中的队列

数据结构 队列的简单理解和基本操作

数据结构队列及其Java代码实现

VSCode自定义代码片段——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程