【数据结构】队列(queue)-链队列(图解、c++、java)

GitHub同步更新(已分类)Data_Structure_And_Algorithm-Review

公众号:URLeisure 的复习仓库
公众号二维码见文末

提示:以下是本篇文章正文内容,下面案例可供参考


链队列概述(图解)

  • 队列除了用顺序存储,也可以用链式存储

  • 两种存储方式如图

顺序队列

链队列

  • 顺序队列是分配一段连续的空间,用两个整形下标 front 和 rear 分别指向队头和队尾。

  • 链队列类似一个单链表,需要两个指针 front 和 rear 分别指向队头和队尾。

  • 从队头出队,从队尾入队,为了出队时删除元素方便,可以增加一个头节点。

  • 链队列需要头节点

顺序队列的基本操作

  • 因为链队列就是一个单链表的形式,因此可以借助单链表的定义。

  • 链队列的操作和单链表一样,只不过它只能队头删除,队尾插入,是操作受限的单链表

  • 首先定义两个结构体(内部类),一个包含数据域和指针域,另一个包含 front 和 rear 指针。

c++代码如下(示例):

typedef struct QNode{//元素节点
    int data;
    QNode *next;
}*Qptr;

struct LinkQueue{
    QNode *front;//头指针
    QNode *rear;//尾指针
};

java代码如下(示例):

public static class Node{//元素节点
    int data;
    Node next;
}
public static class Link{
    Node front;
    Node rear;
}

1.初始化

  • 链队列的初始化,创建一个头节点,头指针和尾指针指向头节点。

c++代码如下(示例):

void InitQueue(LinkQueue &Q){
    Q.front = Q.rear = new QNode;//指向头节点
    Q.front->next = nullptr;
};

java代码如下(示例):

public static void initQueue(Link q){
    q.front = q.rear = new Node();
    q.front.next = null;
}

2.入队

  • 先建立一个新节点,将元素存入该节点的数据域
  • 将新节点插入队尾,尾指针后移。

入队

c++代码如下(示例):

void EnQueue(LinkQueue &Q,int e){
    Qptr s = new QNode;
    s->data = e;
    s->next = nullptr;
    Q.rear->next = s;//从队尾插入
    Q.rear = s;
}

java代码如下(示例):

public static void addQueue(Link q,int e){
    Node s = new Node();
    s.data = e;
    s.next = null;
    q.rear.next = s;
    q.rear = s;
}

3.出队

  • 出队即为删除第一个数据元素,将第一个数据节点跳过。

出队

c++代码如下(示例):

bool DeQueue(LinkQueue &Q,int &e){
    if(Q.front == Q.rear){
        return false;
    }
    Qptr p = Q.front->next;
    Q.front->next = p->next;
    e = p->data;
    if(p == Q.rear){//如果删除的是最后一个元素
        Q.rear = Q.front;//让队尾指向队头,成为空队
    }
    delete p;
    return true;
}

java代码如下(示例):

public static int deQueue(Link q){
    if(q.rear == q.front){
        return -1;
    }
    Node p = q.front.next;
    q.front.next = p.next;
    if(p == q.rear){
        q.rear = q.front;
    }
    return p.data;
}

4.查看队头元素

c++代码如下(示例):

int GetHead(LinkQueue Q){
    if(Q.rear == Q.front){
        return -1;
    }
    return Q.front->next->data;
}

java代码如下(示例):

public static int getHead(Link q){
    if(q.rear == q.front){
        return -1;
    }
    return q.front.next.data;
}

完整代码

c++代码如下(示例):

#include<iostream>

using namespace std;

typedef struct QNode {
    int data;
    QNode *next;
} *Qptr;

struct LinkQueue {
    QNode *front;
    QNode *rear;
};

void InitQueue(LinkQueue &Q) {
    Q.front = Q.rear = new QNode;
    Q.front->next = nullptr;
};

void EnQueue(LinkQueue &Q, int e) {
    Qptr s = new QNode;
    s->data = e;
    s->next = nullptr;
    Q.rear->next = s;
    Q.rear = s;
}

bool DeQueue(LinkQueue &Q, int &e) {
    if (Q.front == Q.rear) {
        return false;
    }
    Qptr p = Q.front->next;
    Q.front->next = p->next;
    e = p->data;
    if (p == Q.rear) {
        Q.rear = Q.front;
    }
    delete p;
    return true;
}

int GetHead(LinkQueue Q) {
    if (Q.rear == Q.front) {
        return -1;
    }
    return Q.front->next->data;
}

int main() {
    LinkQueue q;
    int n, x;
    InitQueue(q);
    cout << "链队列初始化成功!" << endl;
    cout << "输入个数:" << endl;
    cin >> n;
    cout << "依次输入" << endl;
    while (n--) {
        cin >> x;
        EnQueue(q, x);
    }
    cout << "对头元素:" << GetHead(q) << endl;
    cout << "元素依次出队:" << endl;
    while (true) {
        if (DeQueue(q, x)) {
            cout << x << " ";
        } else {
            break;
        }
    }
}

java代码如下(示例):

import java.util.Scanner;
​​
public class A{
    public static class Node {
        int data;
        Node next;
    }public static class Link {
        Node front;
        Node rear;
    }public static void initQueue(Link q) {
        q.front = q.rear = new Node();
        q.front.next = null;
    }public static void addQueue(Link q, int e) {
        Node s = new Node();
        s.data = e;
        s.next = null;
        q.rear.next = s;
        q.rear = s;
    }public static int deQueue(Link q) {
        if (q.rear == q.front) {
            return -1;
        }
        Node p = q.front.next;
        q.front.next = p.next;
        if (p == q.rear) {
            q.rear = q.front;
        }
        return p.data;
    }public static int getHead(Link q) {
        if (q.rear == q.front) {
            return -1;
        }
        return q.front.next.data;
    }public static void main(String[] args) {
        Link q = new Link();
        initQueue(q);
        System.out.println("链队列初始化成功!");
        System.out.println("输入元素个数:");
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        System.out.println("请输入每个元素");
        while (n-- > 0) {
            int x = input.nextInt();
            addQueue(q, x);
        }System.out.println("队头元素是:" + getHead(q));
        System.out.println("出队:");
        int e;
        while ((e = deQueue(q)) != -1) {
            System.out.println("出队元素为:" + e);
        }
    }
}

总结

以上便是今天的复习内容,之后两天会涉及到字符串匹配的BF和KMP,比较难啃。


关注公众号,感受不同的阅读体验

请添加图片描述

下期预告:模式匹配 - BF算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

扑腾的江鱼

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

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

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

打赏作者

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

抵扣说明:

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

余额充值