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

文章目录

  • 目录
    • 一.栈
      • 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


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

索尼XB950N1 震撼人心的重低音

虽然题目是震撼人心的重低音&#xff0c;但是低音可以通过app调节&#xff0c;所以我们可以用这个耳机听各种类型的歌曲。 索尼XB950N1与XB950B1非常相似&#xff0c;但索尼XB950N1提供了主动降噪&#xff0c;续航稍长一些。从蓝牙3.0升级到了蓝牙4.1&#xff0c;改善了传输范…

数据结构和算法(04)---数组,动态内存,vector(c++)

文章目录目录数组1.数组的申明2.数组的初始化3.二维数组4.指向数组的指针5.传递数组给函数动态内存1.new &#xff0c;delete运算符2.数组的动态内存分配vector1.vector基本操作2.vector使用3.vector动态二维数组 初始化和赋值目录 数据结构&#xff1a; 逻辑结构&#xff1a;数…

数据结构和算法(05)---链表(c++)

文章目录目录链表的基本概念1.数组和链表链表的使用1.链表的简单使用2.链表的进阶使用3.链表的高阶使用4.链表的其他操作链表容器list1.list介绍2. list使用3. list与vector之间的区别4.list例子代码目录 数据结构&#xff1a; 逻辑结构&#xff1a;数组&#xff0c;栈&#xf…

论文阅读 状态压缩

状态压缩 Abstract 信息学发展势头迅猛&#xff0c;信息学奥赛的题目来源遍及各行各业&#xff0c;经常有一些在实际应用中很有价值的问题被引入信息学并得到有效解决。然而有一些问题却被认为很可能不存在有效的(多项式级的)算法&#xff0c;本文以对几个例题的剖析&#xf…

数据结构和算法(06)---二叉树(c++)

文章目录目录二叉树1.二叉树的基本概念2.二叉树的应用和时间复杂度3.二叉树的插入4.二叉树的查找5. 二叉树的遍历6.二叉树的删除二叉树的基本操作1.二叉树的基础操作2.代码实现创建二叉树和三种遍历二叉树的方法目录 数据结构&#xff1a; 逻辑结构&#xff1a;数组&#xff0c…

如何转载CSDN博客

前言 对于喜欢逛CSDN的人来说&#xff0c;看别人的博客确实能够对自己有不小的提高&#xff0c;有时候看到特别好的博客想转载下载&#xff0c;但是不能一个字一个字的敲了&#xff0c;这时候我们就想快速转载别人的博客&#xff0c;把别人的博客移到自己的空间里面&#xff0c…

程序员歌曲推荐

更多的时候&#xff0c;不光是电脑和键盘陪着我们度过一天&#xff0c;耳机和音乐也成了IT人生活中必不可少的一部分 上班和下班的路上&#xff0c;心情失落时&#xff0c;失眠时&#xff0c;甚至是工作时都可能会听音乐&#xff0c;让音乐为我们疗伤&#xff0c;让精神得以放…

如何在博客内添加音乐

<center> <iframe border"0" width"480" height"640" src"//music.163.com/outchain/player?type0&amp;id448977181;auto1&amp;height430"> </iframe> </center> 将代码复制到markdown编辑器里&am…

CSDN写博客(字体颜色、大小)

markdown里面的标记语言可以使用标签对来实现对文本文字颜色大小信息的控制。下面给出几个实例&#xff1a; 黑体字示例 微软雅黑示例 华文彩云示例 color#00ffff size可以根据实际大小进行设置&#xff0c;一般不超过7。 红色字体CSDN 红色字体CSDN 使用十六进制颜色值 …

bose qc30 安静的城市是什么样子

使用感受 网友1&#xff08;20岁&#xff09;&#xff1a; 当你带着这个耳机听音乐的时候&#xff0c;有一种感觉&#xff0c;感觉这个世界都是你歌曲里的MV&#xff0c;这个枯燥乏味的世界都被赋予了你心中的那份情感&#xff0c;这种感觉&#xff0c;真的很棒 网友2&#…

DeepLearning.ai 提炼笔记(5-1)-- 循环神经网络

参考博客 Class 5: 序列模型Sequence Models Week 1: 循环神经网络RNN (Recurrent) 文章目录Class 5: 序列模型Sequence ModelsWeek 1: 循环神经网络RNN (Recurrent)目录序列模型-循环神经网络1.序列模型的应用2.数学符号3.循环神经网络模型传统标准的神经网络循环神经网络的…

常见人工智能比赛平台总结

目录1.kaggle比赛1.1 kaggle比赛是什么&#xff1f;1.2 为什么举办kaggle比赛&#xff1f;1.3 kaggle比赛形式是什么&#xff1f;1.4 kaggle比赛的奖励制度是什么&#xff1f;2.阿里天池比赛2.1 阿里天池比赛是什么&#xff1f;2.2 为什么举办阿里天池比赛&#xff1f;2.3 阿里…

机器学习模型评分总结(sklearn)

文章目录目录模型评估评价指标1.分类评价指标acc、recall、F1、混淆矩阵、分类综合报告1.准确率方式一&#xff1a;accuracy_score方式二&#xff1a;metrics2.召回率3.F1分数4.混淆矩阵5.分类报告6.kappa scoreROC1.ROC计算2.ROC曲线3.具体实例2.回归评价指标3.聚类评价指标1.…

kaggle (02) - 房价预测案例(进阶版)

房价预测案例&#xff08;进阶版&#xff09; 这是进阶版的notebook。主要是为了比较几种模型框架。所以前面的特征工程部分内容&#xff0c;我也并没有做任何改动&#xff0c;重点都在后面的模型建造section Step 1: 检视源数据集 import numpy as np import pandas as pd读…

《Head First设计模式》第二章笔记 观察者模式

背景 客户有一个WeatherData对象&#xff0c;负责追踪温度、湿度和气压等数据。现在客户给我们提了个需求&#xff0c;让我们利用WeatherData对象取得数据&#xff0c;并更新三个布告板&#xff1a;目前状况、气象统计和天气预报。 WeatherData对象提供了4个接口&#xff1a; …

libsvm总结

1. 训练 格式&#xff1a;model libsvmtrain(training_label_vector, training_instance_matrix [, libsvm_options]); 这个函数有三个参数&#xff0c;其中 -training_label_vector:训练样本的类标&#xff0c;如果有m个样本&#xff0c;就是m x 1的矩阵&#xff08;类型必须…

《Head First设计模式》第三章笔记 装饰者模式

装饰者模式&#xff08;Decorator Pattern) *利用组合&#xff08;composition&#xff09;和委托&#xff08;delegation&#xff09;可以在运行时实现继承行为的效果&#xff0c;动态地给对象加上新的行为。 *利用继承扩展子类的行为&#xff0c;是在编译时静态决定的&#x…

机器学习中如何解决数据不平衡问题?

文章目录目录什么是数据不平衡问题&#xff1f;数据不平衡会造成什么影响&#xff1f;如何处理数据不平衡问题&#xff1f;1、重新采样训练集1.1随机欠抽样1.2.基于聚类的过采样2.使用K-fold交叉验证3.转化为一分类问题4.组合不同的重采样数据集5.用不同比例重新采样6.多模型Ba…

《Head First设计模式》第四章笔记 工厂模式

之前我们一直在使用new操作符&#xff0c;但是实例化这种行为并不应该总是公开的进行&#xff0c;而且初始化经常会造成耦合问题&#xff0c;工厂模式将摆脱这种复杂的依赖&#xff0c;本次内容包括简单工厂&#xff0c;工厂方法和抽象工厂三种情况。 1 2 3 4 5 6 Duck duck&a…

《Head First设计模式》第五章笔记-单件模式

单件模式 定义&#xff1a;确保一个类只有一个实例&#xff0c;并提供全局访问点。 编写格式&#xff1a; 1 2 3 4 5 6 public class MyClass{ private MyClass(){}//构造方法私有化 public static MyClass getInstance(){ //提供全局访问点 return new My…