数据结构和算法(03)---栈和队列(c++)
文章目錄
- 目錄
- 一.棧
- 1.棧的基本操作
- 2.使用C++模板類實現(xiàn)棧
- 二.隊列
- 1.隊列的基本操作
- 2.循環(huán)隊列
- **循環(huán)隊列順序存儲**
- **循環(huán)隊列鏈式存儲**
- 3.雙端隊列
目錄
- 數(shù)據(jù)結(jié)構(gòu):
- 邏輯結(jié)構(gòu):數(shù)組,棧,隊列,字符串,樹,圖
- 存儲結(jié)構(gòu):順序存儲,鏈式存儲
- C++常用的數(shù)據(jù)結(jié)構(gòu)有:string , stack , queue , deque , vector , list , map , iterators.
一.棧
棧可以看成一種特殊的線性表,特殊之處在于只能在表頭或者表尾進行刪除和插入操作。
1.棧的基本操作
push(): 向棧內(nèi)壓入一個成員;
pop(): 從棧頂彈出一個成員;
empty(): 如果棧為空返回true,否則返回false;
top(): 返回棧頂,但不刪除成員;
size(): 返回棧內(nèi)元素的大小
例子:
#include <iostream> #include <stack>using namespace std;int main(){//定義一個整形的棧stack <int> mStack;cout<<"the size of mStack is:"<<mStack.size()<<endl;//向棧中加入元素mStack.push(1);mStack.push(2);mStack.push(3);mStack.push(4);cout<<"after push , the size of mStack is:"<<mStack.size()<<endl;//彈出棧中的內(nèi)容while(!mStack.empty()){ //棧的遍歷 cout<<"the data will be pop is:"<<mStack.top()<<endl;mStack.pop();cout<<"after pop ,the len of stack is:"<<mStack.size()<<endl;}// for(int i =0 ; i < 4;i++){ // mStack.pop(); //出棧 // cout<<"the "<<i<<" pop is:"<<mStack.top()<<endl; // cout<<"the len "<<i<<" pop is:"<<mStack.size()<<endl; // }return 0; }the size of mStack is:0
after push , the size of mStack is:4
the data will be pop is:4
after pop ,the len of stack is:3
the data will be pop is:3
after pop ,the len of stack is:2
the data will be pop is:2
after pop ,the len of stack is:1
the data will be pop is:1
after pop ,the len of stack is:0
2.使用C++模板類實現(xiàn)棧
雖然C++自帶了stack的模板類,也實現(xiàn)了大部分的棧的操作,但是我們還是需要自己實現(xiàn)棧這種邏輯結(jié)構(gòu)。
#include <iostream> #include <stack>using namespace std;#define MAXSIZE 0XFFFFtemplate<class T> class myStack{private:int top; //棧頂指針,順序存儲中位數(shù)組的下標,所以必須為整形 T* my_s; //棧的存儲空間指針 int maxSize; //棧最大的存儲空間 public://默認的構(gòu)造函數(shù) myStack():top(-1),maxSize(MAXSIZE){my_s = new T[maxSize]; //為棧申請存儲if(my_s == NULL){cerr<<"內(nèi)存分配失敗!"<<endl;exit(1);} }//帶參數(shù)的構(gòu)造函數(shù) myStack(int size):top(-1),maxSize(size){my_s = new T[maxSize]; //為棧申請存儲if(my_s == NULL){cerr<<"內(nèi)存分配失敗!"<<endl;exit(1);}} ~myStack(){cout<<"delete the stack!"<<endl;delete [] my_s; //刪除整個棧 }bool isEmpty();//判空函數(shù)void push(T data); //壓棧函數(shù)void pop(); //出棧函數(shù)T getTopValue(); //取出棧頂元素 int size(); //判斷棧的大小 };//函數(shù)定義 template<class T> bool myStack<T>::isEmpty(){if(top==-1){ //棧頂指針為-1表示棧空 return true;}else{return false;} } template<class T> void myStack<T>::push(T data){if((top+1) < maxSize){ my_s[++top] = data; //先將棧頂指針加一,然后在給棧頂賦值 }else{cout<<"棧滿!"<<endl;} } template<class T> void myStack<T>::pop(){if(top == -1){cout<<"棧空!!"<<endl;}else{top--; //棧頂指針減一 } } template<class T> T myStack<T>::getTopValue(){if(top == -1){cout<<"棧空!!"<<endl;}else{return my_s[top];} } template<class T> int myStack<T>::size(){return top+1; } int main(){// myStack<int> mStack; //創(chuàng)建一個棧 // cout<<"The size of mStack is "<<mStack.size()<<endl; // //壓棧 // mStack.push(1); // mStack.push(2); // mStack.push(3); // mStack.push(4); // cout<<"After push , the size of mStack is "<<mStack.size()<<endl; // while(!mStack.isEmpty()){ // cout<<"the top value of mStack is : "<<mStack.getTopValue()<<endl; // mStack.pop(); // cout<<"After pop , the size of mStack is "<<mStack.size()<<endl; // }myStack<double> mStack; //創(chuàng)建一個棧cout<<"The size of mStack is "<<mStack.size()<<endl;//壓棧mStack.push(1.1);mStack.push(2.4);mStack.push(3.5);mStack.push(4.8);cout<<"After push , the size of mStack is "<<mStack.size()<<endl;//出棧 while(!mStack.isEmpty()){cout<<"the top value of mStack is : "<<mStack.getTopValue()<<endl;mStack.pop();cout<<"After pop , the size of mStack is "<<mStack.size()<<endl; }return 0; }The size of mStack is 0
After push , the size of mStack is 4
the top value of mStack is : 4.8
After pop , the size of mStack is 3
the top value of mStack is : 3.5
After pop , the size of mStack is 2
the top value of mStack is : 2.4
After pop , the size of mStack is 1
the top value of mStack is : 1.1
After pop , the size of mStack is 0
delete the stack!
二.隊列
隊列也是一種特殊的線性表,它只允許在表的一頭插入元素(隊尾),表的另一頭刪除元素(隊頭)。
1.隊列的基本操作
q.empty() 如果隊列為空返回true,否則返回false
q.size() 返回隊列中元素的個數(shù)
q.pop() 刪除隊列首元素但不返回其值
q.push() 在隊尾壓入新元素
q.front() 返回隊首元素的值,但不刪除該元素
q.back() 返回隊列尾元素的值,但不刪除該元素
例子(使用c++自帶的庫實現(xiàn)的)
#include <iostream> #include <queue>using namespace std;int main(){queue<int> mQueue; //創(chuàng)建一個新的隊列cout<<"the size of mQueue is: "<<mQueue.size()<<endl;cout<<"mQueue is empty?: "<<mQueue.empty()<<endl;//入隊mQueue.push(1); mQueue.push(2);mQueue.push(3);mQueue.push(4);cout<<"after push , the size of mQueue is: "<<mQueue.size()<<endl;cout<<"the front data of mQueue is: "<<mQueue.front()<<endl;cout<<"the back data of mQueue is: "<<mQueue.back()<<endl;while(!mQueue.empty()){cout<<"the front data of mQueue is: "<<mQueue.front()<<endl;mQueue.pop();cout<<"after pop , the size of mQueue is: "<<mQueue.size()<<endl; }return 0; }the size of mQueue is: 0
mQueue is empty?: 1
after push , the size of mQueue is: 4
the front data of mQueue is: 1
the back data of mQueue is: 4
the front data of mQueue is: 1
after pop , the size of mQueue is: 3
the front data of mQueue is: 2
after pop , the size of mQueue is: 2
the front data of mQueue is: 3
after pop , the size of mQueue is: 1
the front data of mQueue is: 4
after pop , the size of mQueue is: 0
注意
由于單端隊列的空間利用率非常低,幾乎就是一次性的(只要入隊滿了,然后全部出隊后,便不可再用),所以此處就不討論自己實現(xiàn)單端隊列了。
2.循環(huán)隊列
循環(huán)隊列中判斷隊空的方法是判斷front==rear,隊滿的方法是判斷front=(rear+1)%maxSize。
可以解決單端隊列中空間一次性消耗的問題
循環(huán)隊列順序存儲
#include <iostream> #include <queue>using namespace std;#define MAXSIZE 0XFFFF template<class T> class myQueue{private:int front,rear; //隊頭和隊尾元素 T* my_q; //隊列的存儲空間 int maxSize; //最大的隊列存儲空間public://默認構(gòu)造函數(shù) myQueue():front(-1),rear(-1),maxSize(MAXSIZE){my_q = new T[maxSize]; //申請內(nèi)存if(my_q == NULL){cerr<<"內(nèi)存申請失敗!!"<<endl;exit(1);} }//帶參數(shù)的構(gòu)造函數(shù) myQueue(int size):front(-1),rear(-1),maxSize(size){my_q = new T[maxSize]; //申請內(nèi)存if(my_q == NULL){cerr<<"內(nèi)存申請失敗!!"<<endl;exit(1);} }//析構(gòu)函數(shù) ~myQueue(){cout<<"delete the queue!!!"<<endl;delete [] my_q;} //操作函數(shù)bool isEmpty(); //判空 void push(T data); //入隊操作 void pop(); //出隊操作 T getFrontData(); //獲取隊頭元素 T getRearData(); //獲取隊尾元素 int size(); //獲取隊列長度 };template<class T> bool myQueue<T>::isEmpty(){if(front == rear){ //判空條件 return true;}else{return false;} }template<class T> void myQueue<T>::push(T data){if((rear+1)%maxSize == front){ //隊列滿時候的條件 cout<<"隊列滿了!!"<<endl;}else{my_q[rear] = data; //首先隊尾元素賦值 rear = (rear+1) % maxSize;} }template<class T> void myQueue<T>::pop(){if(rear == front){cout<<"隊列為空!!"<<endl;}else{front = (front+1) % maxSize; //隊頭指針加一 } }template<class T> T myQueue<T>::getFrontData(){if(rear == front){cout<<"隊列為空!!"<<endl;}else{return my_q[front];} }template<class T> T myQueue<T>::getRearData(){if(rear == front){cout<<"隊列為空!!"<<endl;}else{return my_q[rear];} }template<class T> int myQueue<T>::size(){return (rear-front+maxSize)%maxSize; //隊列長度計算 }//main loop int main(){myQueue<int> mQueue;//創(chuàng)建一個新的隊列cout<<"the size of mQueue is: "<<mQueue.size()<<endl;cout<<"mQueue is empty?: "<<mQueue.isEmpty()<<endl;//入隊mQueue.push(1); mQueue.push(2); mQueue.push(3); mQueue.push(4); cout<<"after push , the size of mQueue is: "<<mQueue.size()<<endl;cout<<"the front data of mQueue is: "<<mQueue.getFrontData()<<endl;cout<<"the back data of mQueue is: "<<mQueue.getRearData()<<endl;while(!mQueue.isEmpty()){cout<<"the front data of mQueue is: "<<mQueue.getFrontData()<<endl;mQueue.pop();cout<<"after pop , the size of mQueue is: "<<mQueue.size()<<endl; }return 0; }the size of mQueue is: 0
mQueue is empty?: 1
after push , the size of mQueue is: 4
the front data of mQueue is: 1
the back data of mQueue is: 0
the front data of mQueue is: 1
after pop , the size of mQueue is: 3
the front data of mQueue is: 2
after pop , the size of mQueue is: 2
the front data of mQueue is: 3
after pop , the size of mQueue is: 1
the front data of mQueue is: 4
after pop , the size of mQueue is: 0
delete the queue!!!
循環(huán)隊列鏈式存儲
#include <iostream> using namespace std; template<class T> struct LinkNode{T data;LinkNode<T> *link;LinkNode(T& x,LinkNode<T> *l=NULL){data=x;link=l;} }; template<class T> class LinkedQueue{protected:LinkNode<T> *front,*rear;public:LinkedQueue(){front=rear=NULL;}~LinkedQueue(){makeEmpty();}bool enQueue(T& x){if(front==NULL)front=rear=new LinkNode<T>(x);else{rear=rear->link=new LinkNode<T>(x);}return true;}bool deQueue(T& x){if(isEmpty()) return false;LinkNode<T> *p=front;x=front->data;front=front->link;delete p;return true;}bool getFront(T& x)const{if(isEmpty()) return false;x=front->data;return true;}void makeEmpty(){LinkNode<T> *p;while(front!=NULL){p=front;front=front->link;delete p;}}bool isEmpty()const{return (front==NULL)?true:false;}int getSize()const{LinkNode<T> *p;int count=0;p=front;while(p!=NULL){count++;p=p->link;} return count;} }; void menu(){cout<<"1.入隊"<<endl;cout<<"2.獲取隊首元素"<<endl;cout<<"3.出隊"<<endl;cout<<"4.隊列置空"<<endl;cout<<"5.獲取隊中元素數(shù)量"<<endl;cout<<"6.退出"<<endl; } void function(int num,LinkedQueue<int> *lq){switch(num){int x;case 1:cin>>x;lq->enQueue(x);break;case 2:lq->getFront(x);cout<<x<<endl;break;case 3:lq->deQueue(x);break;case 4:lq->makeEmpty();break;case 5:x=lq->getSize();cout<<x<<endl;break; default:exit(1);} } int main(int argc, char** argv) {LinkedQueue<int> *lq=new LinkedQueue<int>;int num;while(true){menu();cin>>num;function(num,lq);} delete lq;return 0; }3.雙端隊列
可以在兩頭進行插入和刪除操作的隊列
deque k; 定義一個deque的變量(定義時已經(jīng)初始化)
例如: deque k;
k.empty() ------ 查看是否為空范例,是的話返回1,不是返回0
k.clear() ------ 清除隊列里的所有數(shù)據(jù)
k.push_front(i)------ 從已有元素前面增加元素i(隊伍大小不預(yù)設(shè))
k.push_back(i) ------ 從已有元素后面增加元素i(隊伍大小不預(yù)設(shè))
k.pop_front() ------ 清除第一個元素
k.pop_back() ------ 清除最后一個元素
k.front() ------ 顯示第一個元素
k.back() ------ 顯示最后一個元素
k.size() ------ 輸出現(xiàn)有元素的個數(shù)
例子(使用c++自帶的庫實現(xiàn)的)
#include <iostream> #include <deque>using namespace std;//main loop int main(){deque<int> myDeque;//創(chuàng)建一個雙端隊列cout<<"the size of myDeque is: "<<myDeque.size()<<endl;cout<<"myDeque is empty? : "<<myDeque.empty()<<endl; //從對頭插入元素myDeque.push_front(1);myDeque.push_front(2);myDeque.push_front(4);myDeque.push_front(3);//從隊尾插入 myDeque.push_back(0);myDeque.push_back(-1);myDeque.push_back(-1);myDeque.push_back(-3);//從隊頭出隊deque<int> tempQueue = myDeque;while(!tempQueue.empty()){cout<<"the front data of queue is: "<<tempQueue.front()<<endl;tempQueue.pop_front();cout<<"the size of myDeque is: "<<tempQueue.size()<<endl;} //從隊尾出隊deque<int> tempQueue1 = myDeque;while(!tempQueue1.empty()){cout<<"the front data of queue is: "<<tempQueue1.back()<<endl;tempQueue1.pop_back();cout<<"the size of myDeque is: "<<tempQueue1.size()<<endl;} //清空隊列deque<int> tempQueue2 = myDeque;cout<<"the size of myDeque is: "<<tempQueue2.size()<<endl;tempQueue2.clear();cout<<"the size of myDeque1 is: "<<tempQueue2.size()<<endl;return 0; }the size of myDeque is: 0
myDeque is empty? : 1
the front data of queue is: 3
the size of myDeque is: 7
the front data of queue is: 4
the size of myDeque is: 6
the front data of queue is: 2
the size of myDeque is: 5
the front data of queue is: 1
the size of myDeque is: 4
the front data of queue is: 0
the size of myDeque is: 3
the front data of queue is: -1
the size of myDeque is: 2
the front data of queue is: -1
the size of myDeque is: 1
the front data of queue is: -3
the size of myDeque is: 0
the front data of queue is: -3
the size of myDeque is: 7
the front data of queue is: -1
the size of myDeque is: 6
the front data of queue is: -1
the size of myDeque is: 5
the front data of queue is: 0
the size of myDeque is: 4
the front data of queue is: 1
the size of myDeque is: 3
the front data of queue is: 2
the size of myDeque is: 2
the front data of queue is: 4
the size of myDeque is: 1
the front data of queue is: 3
the size of myDeque is: 0
the size of myDeque is: 8
the size of myDeque1 is: 0
總結(jié)
以上是生活随笔為你收集整理的数据结构和算法(03)---栈和队列(c++)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows的命令行窗口运行Pytho
- 下一篇: 特征工程总结