二、栈与递归
1、栈的概念
栈是满足一定约束的线性数据结构,约束是:只允许在栈的一端插入或删除元素,这一端被称为栈顶,另一端称为栈底。
向栈中压入元素,称为push;从栈顶弹出元素,称为pop。
栈的重要性质是先进先出:越早进入栈的元素,出来的时间越晚。
通常用top指示栈顶的位置。
2、代码实现栈的数据结构
#include<iostream>
using namespace std;
struct Stack{//把数据结构封装写成stuck,便于代码复用和调试
int data[10000];
int top = -1;//初始时栈中没有元素,top值为-1
void push(int x){//入栈
top++;
if(top < 10000){
data[top] = x;
}else{ //避免插入元素导致数组访问越界而栈溢出
top--;
count <<"stack overflow" <<endl;
}
}
void pop(){//出栈
if(top >= 0){
top--;
}
}
int topval(){
if(top >= 0){
return data[top];//获取当前栈顶元素的值
}
}
};
int main(){
Stack s;
for(int i = 1; i <= 10; i++){
s.push(i);
}
return 0;
}
标准库里面的stack在头文件< stack >里面
stack< T > s定义一个存储T类型数据的栈s。
3、栈stack< T >的方法总结
方法 | 功能 | 参数类型 | 返回值类型 |
---|---|---|---|
push | 压入元素到栈顶 | T类型 | 无 |
pop | 弹出栈顶元素 | 无 | 无 |
top | 返回栈顶元素 | 无 | T类型 |
empty | 栈是否为空 | 无 | bool类型:false表示不为空,true表示栈为空 |
size | 栈的元素个数 | 无 | 非负整数(size_t类型) |
4、火车出入站问题
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; i++){
cin >> a[i];
}
stack<int> s;
int cur = 1;//记录当前没有压入栈中的元素的起始位置
bool f = 1;
for(int i = 0;i < n;i++){
//如果栈顶不等于a[i],就一直向栈顶push元素
while(s.empty()||s.top() != a[i] && cur <= n){
s.push(cur);
cur++;
}
if(s.empty() || s.top()!=a[i]){
f = 0;
break;
}else{
s.pop();
}
}
if(f){
cout << "legal" << endl;
}else{
cout << "illegal" << endl;
}
return 0;
}
5、递归的概念
递归就是函数调用函数自身,用于解决有重复子问题的问题。
直接递归 求 n! ,n!=n*(n-1)!
int factorial(int n){
return n * factorial(n - 1);
}
6、递归方法求n的阶乘
#include<iostream>
using namespace std;
long long factorial(int n){
if(n <= 1){
return 1;
}
return n * factorial(n-1);
}
int main(){
int n;
cin >> n;
cout << factorial(n) << endl;
return 0;
}
7、汉诺塔问题
#include<iostream>
#include<stack>
using namespace std;
stack<int> S[3];
void move(int x,int y){//栈x的top()移动到栈y的栈顶
int temp = S[x].top();
S[x].pop();
S[y].push(temp);
cout << x << "-->" << y << endl;
}
void hanio(int A,int b,int c,int n){//从A经B将n个盘子移到C
if(n == 1){//终止条件
move(A,C);
}
hanio(A,C,B,n-1);
move(A,C);
hanio(B,A,C,n-1);
}
int main(){
stack<int> S[3];
int n;
cin >> n;
for(int i = n;i >= 1;i--){
S[0].push(i);
}
hanio(0,1,2,n);
while(!S[2].empty()){
cout << S[2].top() << " ";
S[2].pop();
}
return 0;
}