22计算机408考研—数据结构—循环队列和链队(链式队列)

144 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情

2022计算机考研408—数据结构—线性表、栈、队列、数组 手把手教学考研大纲范围内的线性表、栈、队列、数组 22考研大纲数据结构要求的是C/C++,笔者以前使用的都是Java,对于C++还很欠缺, 如有什么建议或者不足欢迎大佬评论区或者私信指出

Talk is cheap. Show me the code. 理论到处都有,代码加例题自己练习才能真的学会

循环队列

循环队列,有点类似双指针数组
左指针存数据后,左指针左移,如果是左端的话,左移到右端
右指针存数据后,右指针右移,如果是右端的话,右移到左端
#include "iostream"

using namespace std;

#define MAXSIZE 10
typedef struct{ //队列结构体:数据,头指针,尾指针
    int *num;
    int front;
    int rear;
}SqQueue;

bool InitQueue(SqQueue &S) {    //初始化队列
    S.num = new int[MAXSIZE];
    S.front = S.rear = 0;   //头指针和尾指针在一块(初始没有数据)
    return true;
}

int QueueLength(SqQueue S) {    //返回长度(尾结点-头结点)
    return (S.rear - S.front + MAXSIZE) % MAXSIZE;//加上MAXSIZE防止出现负数,有可能出现头结点比尾结点大的情况
}

bool QueueInsertHead(SqQueue &S, int data) {    //队列头结点插入
    if ((S.front - 1 + MAXSIZE) % MAXSIZE == S.rear) {  //判断一下是不是满了
        return false;
    }
    S.num[S.front] = data;  //插到头结点
    //因为他是队列,如果头指针在下标0的地方,那么前移就移动到末尾了
    S.front = (S.front - 1 + MAXSIZE) % MAXSIZE;    //头指针前移,防止指针-1小于0,
    return true;
}

bool QueueInsertEn(SqQueue &S, int data) {  //队列尾结点插入
    if ((S.rear + 1) % MAXSIZE == S.front) {    //看是不是满的,尾结点+1可能超过末端,超过末端就从起始端开始算
        return false;
    }
    S.rear = (S.rear + 1) % MAXSIZE;    //后移一位
    S.num[S.rear] = data;   //存放数据
    return true;
}

bool QueueDeleteHead(SqQueue &S, int &data) {   //删除头结点,传给data
    if (S.front == S.rear) {    //如果是空的没办法传
        return false;
    }
    S.front = (S.front + 1) % MAXSIZE;  //头结点后移一位
    data = S.num[S.front];  //把值传给data
    return true;
}

bool QueueDeleteEn(SqQueue &S, int &data) { //删除尾结点,传给data
    if (S.front == S.rear) {    //判断是否为空
        return false;
    }
    data = S.num[S.rear];   //把值传给data
    S.rear = (S.rear - 1 + MAXSIZE) % MAXSIZE;  //尾指针前移
    return true;
}

bool QueueGetHead(SqQueue &S,int &data) {   //得到头结点
    if (S.front == S.rear) {
        return false;
    }
    data = S.num[(S.front + 1) % MAXSIZE];
    return true;
}

bool QueueGetEnd(SqQueue &S, int &data) {   //得到尾结点
    if (S.front == S.rear) {
        return false;
    }
    data = S.num[S.rear];
    return true;
}

bool QueuePrint(SqQueue S) {    //输出队列
    while (S.front != S.rear) {
        S.front = (S.front + 1) % MAXSIZE;
        cout << S.num[S.front] << " ";
        int temp = S.num[S.front];
    }
    cout << "\n";
}


int main() {
    SqQueue queue;
    InitQueue(queue);
    QueueInsertHead(queue, 10);
    QueueInsertEn(queue, 40);
    QueueInsertHead(queue, 20);
    QueueInsertEn(queue, 30);
    QueuePrint(queue);
    int data;
    QueueDeleteEn(queue, data);
    cout << "删除尾结点:" << data << "\n";
    QueueDeleteHead(queue, data);
    cout << "删除头结点:" << data << "\n";
    QueueGetHead(queue, data);
    cout << "得到头结点:" << data << "\n";
    QueueGetEnd(queue, data);
    cout << "得到尾结点:" << data << "\n";
    cout << "得到长度:" << QueueLength(queue) << "\n";
    QueuePrint(queue);
}

在这里插入图片描述

链队(链式队列)

每个结点有一个指向下一位的指针
相对双向循环链表简单
#include "iostream"

using namespace std;

typedef struct QNode {  //结点结构体:值,下一位的指针
    int data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct {    //队列包含一个头指针,一个尾指针
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;

bool InitQueue(LinkQueue &Q) {  //初始化队列
    Q.front = Q.rear = new QNode;   //创建头尾结点
    Q.front->next = NULL;           //头结点的下一个为空
    Q.front->data = Q.rear->data = NULL;    //初始时,头尾结点值为NULL
    return true;
}

bool LinkQueueInsertEnd(LinkQueue &Q, int data) {   //添加元素到队尾
    if (Q.front == Q.rear && Q.front->data == NULL) {   //如果是第一次进来
        Q.rear->data = data;    //赋初值
        return true;
    }
    Q.rear->next= new QNode;
    Q.rear->next->data = data;  //给尾结点的下一个赋值
    Q.rear = Q.rear->next;      //尾结点指向尾结点的下一个
    Q.rear->next = NULL;        //尾结点的下一个为空
    return true;
}

bool LinkQueueDeleteHead(LinkQueue &Q, int &data) { //删除头结点
    if (Q.front == Q.rear) {
        return false;
    }
    QNode *temp = new QNode;
    data = Q.front->data;   //保存头结点的值
    Q.front = Q.front->next;    //头指针指向下一位
}

bool LinkQueueGetHead(LinkQueue &Q, int &data) {    //得到头结点
    if (Q.front != Q.rear) {    //队列不为空就返回
        data = Q.front->data;
        return true;
    }
    return false;
}

void LinkQueuePrint(LinkQueue Q) {  //输出队列的值
    while (Q.front != Q.rear->next) {
        cout << Q.front->data << " ";
        Q.front = Q.front->next;
    }
    cout << "\n";
}

int main() {
    LinkQueue linkQueue;
    InitQueue(linkQueue);
    LinkQueueInsertEnd(linkQueue, 10);
    LinkQueueInsertEnd(linkQueue, 20);
    LinkQueueInsertEnd(linkQueue, 30);
    LinkQueueInsertEnd(linkQueue, 40);
    LinkQueuePrint(linkQueue);
    int val;
    LinkQueueDeleteHead(linkQueue, val);
    cout << "删除的头结点值为:" << val << "\n";
    LinkQueueGetHead(linkQueue, val);
    cout << "得到的头结点值为:" << val << "\n";
    return 0;
}

在这里插入图片描述