震驚篇(一)——如何通過面向物件的思想實現環形佇列
阿新 • • 發佈:2019-02-18
從今天開始寫資料結構的博文了,為什麼呢?作者還是一個小小的大學生,因為資料結構實在是晦澀難懂,所以想在課下總結一下,寫的有點low勿噴撒。
今天我們通過類的思想來實現環形佇列。
首先談一下什麼是佇列。在百度百科上是這樣定義的:“佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。” 佇列之所以稱做是一種資料結構,是因為他有規定的操作方法,即First In First Out(FIFO),先進先出,也就是我們日常生活中排隊的思想。 環形佇列是一種特殊的佇列,顧名思義,它是一個環狀的,秩序記錄頭尾即可操作。他可以減少記憶體資源的浪費,是一種綠色方法。 如果通過類的思想實現一個環形佇列,那就需要考慮到它需要哪些成員變數、哪些成員函式。本次通過陣列class MyQueue { public: MyQueue(int queueCapacity);//建構函式,用於定義一個新的佇列,並初始化佇列 virtual ~MyQueue();//解構函式用於清除佔用的記憶體 void ClearQueue();//將佇列元素全部清空 bool QueueEmpty() const;//用於判斷佇列是否為空 bool QueueFull() const;//用於判斷佇列是否為滿 int QueueLength() const;//用於測量佇列長度 bool EnQueue(int element);//佇列入列 bool DeQueue(int &element);//佇列處理 void QueueTraverse();//佇列遍歷 private: int *m_pQueue;//佇列指標,用於檢索佇列屬性和方法 int m_iQueueLen;//佇列長度屬性 int m_iQueueCapacity;//佇列容量屬性 int m_iHead;//隊頭位置 int m_iTail;//隊尾位置 };
相應的成員變數和成員函式就是以上。
先看一下成員變數:
為了便於操作,佇列的頭位置、尾位置需要記錄。 需要一個佇列指標用於檢索成員變數和函式。 需要記錄佇列長度和佇列上限。對於成員函式:
建立佇列、刪除佇列、入列、出列、遍歷、判空判滿、獲取隊列當前長度、清空佇列,這些函式是基本的實現成員函式。
再看一下實際程式碼,具體實現方法:
#include "MyQueue.h" #include <iostream> using namespace std; //建構函式 MyQueue::MyQueue(int queueCapacity)//傳入佇列初始化容量 { //將佇列容量賦值給屬性 m_iQueueCapacity = queueCapacity; //給出記憶體 m_pQueue = new int[m_iQueueCapacity]; //清除內部元素 ClearQueue(); } MyQueue::~MyQueue() { //清除記憶體 delete[]m_pQueue; //指標指向null; m_pQueue = NULL; } //清除佇列元素 void MyQueue::ClearQueue() { m_iHead = 0; m_iTail = 0; m_iQueueLen = 0; } bool MyQueue::QueueEmpty() const { if (m_iQueueLen == 0) { return true; } else { return false; } //return m_iQueueLen == 0 ? true : false; } bool MyQueue::QueueFull() const { if (m_iQueueLen == m_iQueueCapacity) { return true; } else { return false; } } int MyQueue::QueueLength() const { return m_iQueueLen; } bool MyQueue::EnQueue(int element) { if (QueueFull()) { cout << "The queue is full! EnQueue failed!" << endl; return false; } else { m_pQueue[m_iTail] = element; m_iTail=(m_iTail++)%m_iQueueCapacity; m_iQueueLen++; return true; } } bool MyQueue::DeQueue(int &element) { if (QueueEmpty()) { cout << "DeQueue failed!The queue is empty!" << endl; return false; } else { element = m_pQueue[m_iHead]; m_iQueueLen -- ; m_iHead = (m_iHead++) % m_iQueueCapacity; return true; } } void MyQueue::QueueTraverse() { for (int i = m_iHead; i < m_iHead + m_iQueueLen; i++) { cout << m_pQueue[i % m_iQueueCapacity]; } }
1.建立佇列時,通過建構函式傳入佇列上限,例項化一個佇列,申請記憶體,將佇列清空初始化。 2.刪除佇列時,通過解構函式釋放記憶體。 3.清空佇列,即將隊頭隊尾初始化為起始位置,將佇列長度置為0。 4.判空,即判斷佇列長度是否是0,是0為空,否則為非空。 5.判滿,即判斷佇列長度是否為佇列上限,是則滿,否則非滿。 6.入列,出列,遍歷要注意佇列長度、隊頭隊尾索引大小的邏輯問題,這裡請各位自行理解程式碼。