资料结构 伫列(Queue)

目录:资料结构系列文章

伫列(Queue)是一种First-In-First-Out的资料结构
如同字面上意思,就像排队买票的队列一样
先买完票的人才能先出去,进来后面排队的人要等到前面的人都买完才能出去

使用c++实作

使用阵列(Array)实作

这里是採用记忆体空间会重複使用的Circular Queue

#include <iostream>using namespace std;template <typename T>class QueueArray{public:    QueueArray() : front(-1), back(-1), capacity(1)    {        ptr = new T[capacity];    }    void Push(T data) // 把资料放到最后端    {        if ((back + 1) % capacity == front) // 如果每个位置都放满了,把配置阵列大小变为2倍再放资料        {            DoubleCapacity();        }        if (isEmpty()) // 如果Queue为空,则Push时front要另外加1,让front变为0        {            front++;        }        ptr[(back + 1) % capacity] = data;        back = (back + 1) % capacity;    }    void Pop() // 把顶端的资料移除    {        if (isEmpty())        {            cout << "Queue is empty." << endl;        }        else        {            front++; // 只需要把front加1就行,因为之后如果有资料Push进来,会直接覆盖掉原本的,不须花费成本再delete跟new        }    }    bool isEmpty() // 回传Queue是否为空    {        return (front == -1);    }    int getSize() // 回传Queue大小    {        if (isEmpty())        {            return 0;        }        else if (front == back) // 如果front和back为同一个位置        {            return 1;        }        else if (front < back) // 如果front在back前面        {            return back - front + 1;        }        else // 如果front在back后面        {            return capacity - (front - back) + 1;        }    }    T getFront() // 回传最前端的资料    {        if (isEmpty())        {            cout << "Queue is empty." << endl;            return 0; // 回传0是因为不知道T是什么型态,如果回传别的数值会很容易出错        }        return ptr[front];    }    T getBack() // 回传最后端的资料    {        if (isEmpty())        {            cout << "Queue is empty." << endl;            return 0; // 回传0是因为不知道T是什么型态,如果回传别的数值会很容易出错        }        return ptr[back];    }private:    int front;            // 最前端的index    int back;             // 最后端的index    int capacity;         // 目前配置空间的大小    int *ptr;             // 目前配置的阵列(第一个元素的指标)    void DoubleCapacity() // 把配置的阵列变成两倍的大小    {        int *newptr = new int[capacity * 2];        int j = front - 1;        for (int i = 0; i < capacity; i++) // 把旧的阵列里的资料複製到新的阵列        {            newptr[i] = ptr[(++j) % capacity];        }        delete[] ptr;        ptr = newptr;        front = 0;        back = capacity - 1;        capacity *= 2;    }};int main(){    QueueArray<int> q;    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(24);    cout << "After push 24:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(8);    q.Push(23);    cout << "After push 8, 23:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << "After pop 24:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(13);    cout << "After push 13:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << "After pop 8:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(35);    cout << "After push 35:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(9);    cout << "After push 9:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(64);    cout << "After push 64:\n";    cout << q.isEmpty() << " " << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    return 0;}

output:

Queue is empty.Queue is empty.1 0 0 00 24 24 10 24 23 30 8 23 20 8 13 30 23 13 20 23 35 30 23 9 40 23 64 5

使用链结串列(Linked List)实作

一样我们稍微修改一下之前的linklist后就直接继承
SinglyLinkedList.h

#include <iostream>using namespace std;template <typename T>class SinglyLinkedList; // 为了将class SinglyLinkedList设成class ListNode的friend,必须先宣告template <typename T>class ListNode{public:    ListNode(T x) : value(x), next(0) {} // 使用c++的成员初始化串列,将value初始化为x,next初始化为0private:    T value;    ListNode<T> *next;    friend class SinglyLinkedList<T>; // 将class SinglyLinkedList宣告为friend,让class SinglyLinkedList可以存取ListNode的private成员};template <typename T>class SinglyLinkedList{public:    SinglyLinkedList() : head(0), size(0),tail(0) {}    int getSize() // 回传list资料个数    {        return size;    }    bool isEmpty() // 回传list是否为空    {        return head == 0;    }protected: // 设为protected是因为不想让非成员函式可以存取到    void PushFront(T data) // 在list的最前端塞入资料    {        ListNode<T> *NewNode = new ListNode<T>(data);        if (head == 0)        {            head = NewNode;            tail = NewNode;        }        else        {            NewNode->next = head;            head = NewNode;        }        ++size;    }    void PushBack(T data) // 在list的最后端塞入资料    {        if (head == 0)        {            PushFront(data);        }        else        {            ListNode<T> *NewNode = new ListNode<T>(data);            tail->next=NewNode;            tail = NewNode;            ++size;        }    }    ~SinglyLinkedList()    {        ListNode<T> *current = head;        while (current != 0)        {            ListNode<T> *NextNode = current->next;            delete current;            current = NextNode;        }        head = 0; // 当指标被delete后, 将其指向NULL, 可以避免不必要bug    }    void PopFront() // 移除list中最前端的资料    {        if (head == 0)        {            cout << "List is empty." << endl;        }        else if(head!=0&& head->next==0) // 当list只有一笔资料时        {            delete head;            head = 0;            tail = 0;            --size;        }        else        {            ListNode<T> *NextNode = head->next;            delete head;            head = NextNode;            --size;        }    }    T getHead() // 回传第一个资料    {        if (isEmpty())        {            cout << "List is empty." << endl;            return 0;        }        else        {            return head->value;        }    }    T getTail() // 回传最后一个资料    {        if (isEmpty())        {            cout << "List is empty." << endl;            return 0;        }        else        {            return tail->value;        }    }private:    ListNode<T> *head;    ListNode<T> *tail;    int size;};
#include <iostream>#include "SinglyLinkedList.h"using namespace std;template <typename T>class QueueList : public SinglyLinkedList<T>{public:    void Push(T data) // 在最后端放入资料    {        SinglyLinkedList<T>::PushBack(data);    }    void Pop() // 移除最前端的资料    {        if (SinglyLinkedList<T>::isEmpty())        {            cout << "Queue is empty." << endl;        }        else        {            SinglyLinkedList<T>::PopFront();        }    }    T getFront() // 取得最前端的资料    {        if (SinglyLinkedList<T>::isEmpty())        {            cout << "Queue is empty." << endl;            return 0;        }        else        {            SinglyLinkedList<T>::getHead();        }    }    T getBack() // 取得最后端的资料    {        if (SinglyLinkedList<T>::isEmpty())        {            cout << "Queue is empty." << endl;            return 0;        }        else        {            SinglyLinkedList<T>::getTail();        }    }};int main(){    QueueList<int> q;    cout << q.isEmpty() << endl;    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(24);    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(8);    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << q.isEmpty() << endl;    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(23);    cout << q.isEmpty() << endl;    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(13);    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(35);    q.Push(36);    cout << q.isEmpty() << endl;    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Push(38);    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    q.Pop();    cout << q.getFront() << " " << q.getBack() << " " << q.getSize() << endl;    cout << q.isEmpty() << endl;    return 0;}

output:

1Queue is empty.Queue is empty.0 0 024 24 1Queue is empty.Queue is empty.0 0 08 8 11Queue is empty.Queue is empty.0 0 0023 23 123 13 213 13 1013 36 335 36 235 38 336 38 238 38 10

使用python实作

class Queue:    def __init__(self):        self.queue = []  # 使用串列来实作        self.size = 0    def Push(self, data):  # 把资料放到最后端        self.queue.append(data)  # append函式 把资料加进串列的末端        self.size += 1    def Pop(self):  # 把最前端的资料移除        if self.size == 0:            print("Queue is empty.")        else:            self.queue = self.queue[1:]  # 把串列的第一个元素移除            self.size -= 1    def getFront(self):        if self.size == 0:            print("Queue is empty.")            return 0        else:            return self.queue[0]    def getBack(self):  # 回传最后端的资料        if self.size == 0:            print("Queue is empty.")            return 0        else:            return self.queue[self.size - 1]    def isEmpty(self):  # 回传queue是否为空        return self.size == 0    def getSize(self):  # 回传queue大小        return self.sizedef main():    s = Queue()    s.Pop()    print(s.isEmpty())    print(s.getFront())    print(s.getBack())    print(s.getSize())    s.Push(2)    print(s.isEmpty())    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Push(4)    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Push(6)    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Pop()    print(s.isEmpty())    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Pop()    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Push(8)    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Push(10)    print(s.isEmpty())    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize())    s.Pop()    print(s.getFront(), end=" ")    print(s.getBack(), end=" ")    print(s.getSize(), end=" ")    print(s.isEmpty())if __name__ == "__main__":    main()

output:

Queue is empty.TrueQueue is empty.0Queue is empty.00False2 2 12 4 22 6 3False4 6 26 6 16 8 2False6 10 38 10 2 False

上一篇:资料结构 堆叠(Stack)


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章