数据结构-03-队列

队列

1.队列简介:

队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,不能再任意位置插入和删除。
进行插入操作的端称为队尾,进行删除操作的端称为队头。

这里写图片描述

2.使用顺序表实现队列结构:

2.1 队列类的定义:

template<typename Type>
class SequenceQueue {
public:
    SequenceQueue(int size) :front(0), count(0), maxSize(size) {
        elements = new Type[size];
        if (elements == nullptr) {
            cout << "初始化队列对象出错" << endl;
            exit(1);
        }
    }
    ~SequenceQueue() {
        delete[] elements;
    }
    //返回队列的信息的方法
    bool IsEmpty();
    bool IsFull();
    //对队列内元素的操作
    void MakeEmpty();
    bool Append(const Type item);
    Type Delete();
    Type Get();
    //基本方法
    void Print();
private:
    int rear;
    int front;
    int count;
    int maxSize;
    Type * elements;
};

2.2 顺序表队列的5个私有属性:

使用顺序表实现队列,下面5个属性必不可少

属性功能
rear队列的尾部位置
front队列的头部位置
count队列元素的总数
maxSize队列的最大长度
elements存储队列元素的载体,一个数组

2.3 顺序表队列的工作原理:

通过改变rear和front的值,改变队列的头位置和尾位置,实现队列的增删
元素从队列的尾部进入队列,从头部离开队列

1)顺序表队列删除元素

这里写图片描述

若队列如上图所示,队列元素为a3到an,a3位于队头,an位于队尾,现在调用Delete()删除一个元素,
步骤一:front的值增1,队头向右移一位
步骤二:count的值减1,队列总元素数减1

template<typename Type>
Type SequenceQueue<Type>::Delete() {
    if (IsEmpty()) {
        cout << "没有可删除的元素" << endl;
        exit(1);
    }
    Type temp = elements[front];
    front = front + 1;
    count--;
    return temp;
}

由上的分析可以看出,顺序表队列在删除队列元素时并没有将队列元素从内存中删除

2)顺序表队列添加元素

队列添加元素和删除元素的原理相同,与删除元素不同的是首先要将添加的数据存入到载体数组中,然后再右移动队尾

template<typename Type>
bool SequenceQueue<Type>::Append(const Type item) {
    if (IsFull()) {
        cout << "队列超载" << endl;
        return false;
    }
    elements[rear] = item;
    rear = rear + 1;
    count++;
    return true;
}

2.4 顺序表队列的优化:

顺序表队列的一个问题:

如上程序,rear和front的移动方式均为自增

rear = rear + 1;
front = front + 1;

如果队列需要快速读取一小部分数据并立即将这部分数据删除,在同一时间内在队列中的数据很少,即maxSize可以是一个很小的数
但是由于数据的载体是一个顺序表,不停地向一个方向移动rear和front需要一个很多的顺序表
这时可以将顺序表设计成环形的,这个环形顺序表的长度设置为保证比maxSize大,这样就可以使队列只使用一小部分内存即可完成上述工作

这里写图片描述

如果使用链表来实现队列,则环形表非常容易实现,但是顺序表则无法实现环形的,因为数组是有向无循环的,但是可以改变rear和front的自增方式间接实现目标效果

rear = (rear + 1) % maxSize;
front = (front + 1) % maxSize;

3.使用链表实现队列结构:

原理和循序表队列的原理完全相同,这里只给出实现的代码:

template<typename Type> class LinkedQueue;

template<typename Type>
class LinkedQueueNode
{
private:
    friend typename LinkedQueue<Type>;
    //构造函数和析构函数
    LinkedQueueNode() :pnext(nullptr) {}
    LinkedQueueNode(const Type item, LinkedQueueNode<Type> * next = nullptr) :data(item), pnext(next) {}
    ~LinkedQueueNode() {
        pnext = nullptr;
    }
public:
    Type GetData();
private:
    Type data;
    LinkedQueueNode * pnext;
};
//获取链表节点中的数据
template<typename Type> Type LinkedQueueNode<Type>::GetData() {
    return this->data;
}
#pragma once
#include"LinkedQueueNode.h"

template<typename Type>
class LinkedQueue {
public:
    LinkedQueue(int size) :front(0), count(0), maxSize(size), head(new LinkedQueueNode<Type>()) {
        LinkedQueueNode<Type> * pmove = head;
        for (int i = 0; i < size; i++){
            LinkedQueueNode<Type> * pnode = new LinkedQueueNode<Type>;
            pmove->pnext = pnode;
            pmove = pmove->pnext;
        }
        pmove->pnext = head->pnext;
    }
    ~LinkedQueue() {
        MakeEmpty();
        delete head;
    }
    //返回队列的信息的方法
    bool IsEmpty();
    bool IsFull();
    //对队列内元素的操作
    void MakeEmpty();
    bool Append(const Type item);
    Type Delete();
    Type Get();
    //基本方法
    void Print();

private:
    int rear;
    int front;
    int count;
    int maxSize;
    LinkedQueueNode<Type> * head;
};

template<typename Type>
void LinkedQueue<Type>::MakeEmpty() {
    LinkedQueueNode<Type> *pdel;
    while (head->pnext != nullptr)
    {
        pdel = head->pnext;
        head->pnext = pdel->pnext;
        delete pdel;
    }
}

template<typename Type>
bool LinkedQueue<Type>::IsEmpty() {
}

template<typename Type>
bool LinkedQueue<Type>::IsFull() {
}

template<typename Type>
bool LinkedQueue<Type>::Append(const Type item) {
    LinkedQueueNode<Type> * pmove = head;
    for (int i = 0; i <= rear; i++){
        pmove = pmove->pnext;
    }
    pmove->data = item;
    rear++;
    count++;
    return true;
}

template<typename Type>
Type LinkedQueue<Type>::Delete() {
    front++;
    count--;
    return head->pnext->data;
}

template<typename Type>
Type LinkedQueue<Type>::Get() {
    Type temp = 0;
    return temp;
}

template<typename Type>
void LinkedQueue<Type>::Print() {

    LinkedQueueNode<Type> *pmove = head->pnext;
    cout << endl << "head";
    for (int i = 0; i < front; i++){
        pmove = pmove->pnext;
    }
    for (int i = front; i < rear; i++) {
        cout << "->" << pmove->data;
        pmove = pmove->pnext;
    }
    cout << "-over" << endl;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值