文章目录

  • 目录
    • 一.栈
      • 1.栈的基本操作
      • 2.使用C++模板类实现栈
    • 二.队列
      • 1.队列的基本操作
      • 2.循环队列
        • **循环队列顺序存储**
        • **循环队列链式存储**
      • 3.双端队列

目录

  • 数据结构:

    • 逻辑结构:数组,栈,队列,字符串,树,图
    • 存储结构:顺序存储,链式存储
  • C++常用的数据结构有:string , stack , queue , deque , vector , list , map , iterators.

一.栈

栈可以看成一种特殊的线性表,特殊之处在于只能在表头或者表尾进行删除和插入操作。

1.栈的基本操作

push(): 向栈内压入一个成员;
pop(): 从栈顶弹出一个成员;
empty(): 如果栈为空返回true,否则返回false;
top(): 返回栈顶,但不删除成员;
size(): 返回栈内元素的大小

例子:

#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;//弹出栈中的内容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++模板类实现栈

虽然C++自带了stack的模板类,也实现了大部分的栈的操作,但是我们还是需要自己实现栈这种逻辑结构。

#include <iostream>
#include <stack>using namespace std;#define MAXSIZE 0XFFFFtemplate<class T>
class myStack{private:int top;  //栈顶指针,顺序存储中位数组的下标,所以必须为整形 T* my_s;  //栈的存储空间指针 int maxSize;  //栈最大的存储空间 public://默认的构造函数 myStack():top(-1),maxSize(MAXSIZE){my_s = new T[maxSize];  //为栈申请存储if(my_s == NULL){cerr<<"内存分配失败!"<<endl;exit(1);} }//带参数的构造函数 myStack(int size):top(-1),maxSize(size){my_s = new T[maxSize]; //为栈申请存储if(my_s == NULL){cerr<<"内存分配失败!"<<endl;exit(1);}} ~myStack(){cout<<"delete the stack!"<<endl;delete [] my_s;  //删除整个栈 }bool isEmpty();//判空函数void push(T data); //压栈函数void pop();    //出栈函数T getTopValue();  //取出栈顶元素 int size(); //判断栈的大小
};//函数定义
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;  //创建一个栈
//  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;  //创建一个栈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() 返回队列中元素的个数
q.pop() 删除队列首元素但不返回其值
q.push() 在队尾压入新元素
q.front() 返回队首元素的值,但不删除该元素
q.back() 返回队列尾元素的值,但不删除该元素

例子(使用c++自带的库实现的)

#include <iostream>
#include <queue>using namespace std;int main(){queue<int> mQueue; //创建一个新的队列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

注意

由于单端队列的空间利用率非常低,几乎就是一次性的(只要入队满了,然后全部出队后,便不可再用),所以此处就不讨论自己实现单端队列了。

2.循环队列

循环队列中判断队空的方法是判断front==rear,队满的方法是判断front=(rear+1)%maxSize。
可以解决单端队列中空间一次性消耗的问题

循环队列顺序存储

#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://默认构造函数 myQueue():front(-1),rear(-1),maxSize(MAXSIZE){my_q = new T[maxSize];  //申请内存if(my_q == NULL){cerr<<"内存申请失败!!"<<endl;exit(1);} }//带参数的构造函数 myQueue(int size):front(-1),rear(-1),maxSize(size){my_q = new T[maxSize];  //申请内存if(my_q == NULL){cerr<<"内存申请失败!!"<<endl;exit(1);} }//析构函数 ~myQueue(){cout<<"delete the queue!!!"<<endl;delete [] my_q;} //操作函数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;//创建一个新的队列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!!!

循环队列链式存储

#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.获取队中元素数量"<<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的变量(定义时已经初始化)
例如: deque k;

k.empty() ------ 查看是否为空范例,是的话返回1,不是返回0
k.clear() ------ 清除队列里的所有数据
k.push_front(i)------ 从已有元素前面增加元素i(队伍大小不预设)
k.push_back(i) ------ 从已有元素后面增加元素i(队伍大小不预设)
k.pop_front() ------ 清除第一个元素
k.pop_back() ------ 清除最后一个元素
k.front() ------ 显示第一个元素
k.back() ------ 显示最后一个元素
k.size() ------ 输出现有元素的个数

例子(使用c++自带的库实现的)

#include <iostream>
#include <deque>using namespace std;//main loop
int main(){deque<int> myDeque;//创建一个双端队列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


数据结构和算法(03)---栈和队列(c++)相关推荐

  1. 研磨数据结构与算法-03栈与队列

    一,栈 public class MyStack { //底层实现是一个数组 private long[] arr; private int top; /** * 默认的构造方法 */ public ...

  2. 数据结构与算法--利用栈实现队列

    利用栈实现队列 上一节中说明了栈的特点 后进先出,我们用数组的方式实现了栈的基本操作api,因此我们对栈的操作是不考虑排序的,每个api的操作基本都是O(1)的世界,因为不考虑顺序,所以找最大,最小值 ...

  3. 数据结构与算法(2)——栈和队列

    前言:题图无关,只是好看,接下来就来复习一下栈和队列的相关知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 栈 什么 ...

  4. 【数据结构与算法】栈与队列

    栈 一.什么是栈? 1.后进者先出,先进者后出,这就是典型的"栈"结构. 2.从栈的操作特性来看,是一种"操作受限"的线性表,只允许在端插入和删除数据. 二.为 ...

  5. 数据结构与算法之栈与队列:java实现

    闻理似悟,遇境则迷!!! 栈与队列来说也算是一种特殊的线性表,栈的特点是后进先出,队列的特点是先进先出. 栈 栈的特点是后进先出,栈的操作只有出栈和入栈(也叫压栈),除此之外,还包含栈顶与栈底的指向以 ...

  6. 【数据结构与算法】栈与队列【C语言版】

    目录 3.1 栈和队列的定义和特点 3.2 栈.队列与一般线性表的区别 3.3 栈的表示和操作的实现 顺序栈与顺序表 ================= 顺序栈的表示 顺序栈初始化 判断顺序栈是否为空 ...

  7. 用JS描述的数据结构及算法表示——栈和队列(基础版)

    前言:找了上课时数据结构的教程来看,但是用的语言是c++,所以具体实现在网上搜大神的博客来看,我看到的大神们的博客都写得特别好,不止讲了最基本的思想和算法实现,更多的是侧重于实例运用,一边看一边在心里 ...

  8. 数据结构与算法(二) 栈与队列(代码示例)

    数据结构与算法 栈与队列 1. 数组和链表实现栈 2. 用O(1)的时间复杂度求栈中的最小元素 3. 链表和数组实现队列 4. 用两个栈模拟队列操作 1. 数组和链表实现栈 链表的方式: /*** 描 ...

  9. 数据结构与算法 | 用栈实现队列

    之前的几章我讲解了栈和队列的基本特性和一些基本的操作方法,那么如何能利用栈来实现队列呢? 下面我来讲解下具体思路,栈的特性先进后出,队列是先进先出,如果要模拟队列的这个特性,我们就必须用到两个栈. 一 ...

  10. Python数据结构与算法(六)--栈和队列

    栈和队列 栈(stack),有些地方称为堆栈,是一种容器,可存入数据元素.访问元素.删除元素,它的特点在于只能允许在容器的一端(称为栈顶端指标,英语:top)进行加入数据(英语:push)和输出数据( ...

最新文章

  1. “编程能力差,90%的人会输在这点上!”谷歌开发:其实都是在瞎努力
  2. 支撑亿级用户“刷手机”​,百度Feed流背后的新技术装备有多牛?
  3. vim graphics
  4. 【译】Private Image Analysis with MPC Training CNNs on Sensitive Data
  5. boost::mp11::mp_append相关用法的测试程序
  6. 分布式队列编程优化篇
  7. linux shell运行脚本命令行参数,shell脚本命令行参数简介
  8. Java 的体系结构包含_第一章 java体系结构介绍
  9. 使用UMDH进行内心泄露分析
  10. matlab-imresize-最近邻插值、双线性插值、双三次插值学习总结
  11. python十六进制转为二进制_Python进制转换(二进制、十进制和十六进制)
  12. CKEditor5系列二:创建简单插件
  13. MVX-Net: PointFusion 在mmdetection3d中的实现
  14. 求1-100之间的和
  15. Swift 方法的多面性
  16. WorldFirst能用于PayPal提现吗?怎么操作?
  17. mongoBooster里使用mongo的foreach方法示例
  18. 如何自己搭建一个个人网站?
  19. 关于Bootstrap的一些使用
  20. simulink模块,提供xpctarget下驱动源码

热门文章

  1. SIP协议(基础技术知识)
  2. ARMV4,ARMV4T,ARMV4I的意义
  3. 一个数据包大小是多少k_算法交流: 6046 数据包的调度机制 【2.6基本算法之动态规划】...
  4. LSGO软件技术团队2015~2016学年第十六周(1214~1220)总结
  5. 【转】QT布局QGridLayout QHBoxLayout QVBoxLayout简要分析!!
  6. 【转】ABP源码分析三十九:ABP.Hangfire
  7. 【转】Dynamics CRM 365零基础入门学习(四)Dynamics 使用profiler插件调试流程
  8. System中不存在类型或命名空间名称Transactions
  9. Python操作Kafka爬坑
  10. 设计模式(五)行为型模式