栈的解析及C++实现

介绍

栈是一种线性结构,它有以下几个特点:

1)栈中数据是按照“后进先出”方式进出栈的

2)向栈中添加/删除数据时,只能从栈顶进行操作


栈通常包括三种操作:top、pop、push

top -- 返回栈顶元素

pop -- 返回并删除栈顶元素

push -- 向栈中添加元素


常见错误:栈空时进行top或pop操作

解决方法:用户在使用top或pop操作时,需确保栈是非空的


————————————————————————————————————————————————————————————————————————————

栈的示意图


出栈



入栈




————————————————————————————————————————————————————————————————————————————

栈的C++实现

顺序栈

顺序栈结构实现的头文件SeqStack.h

#ifndef SeqStack_byNim
#define SeqStack_byNim

#include<iostream>
using namespace std;

const int MAX_SIZE=100;

template <class T>
class SeqStack
{
	private:
		T *data;
		int topPointer;
	public:
		SeqStack();
		~SeqStack();
		
		void push(T e);
		T pop();
		T top();
		
		bool empty();
};

template <class T>
SeqStack<T>::SeqStack()
{
	topPointer=-1;
	data=new T[MAX_SIZE];
}

template <class T>
SeqStack<T>::~SeqStack()
{
	topPointer=-1;
	delete []data;
}

template <class T>
void SeqStack<T>::push(T e)	//入栈操作
{
	if(topPointer==MAX_SIZE-1)		
	{
		cout<<"OVERFLOW"<<endl;			return;
	}
	topPointer++;
	data[topPointer]=e;
}

template <class T>
T SeqStack<T>::pop()	//出栈操作 
{
	if(topPointer==-1)
	{
		throw "栈空";
	}
	return data[topPointer--];
}

template <class T>
T SeqStack<T>::top()
{
	if(topPointer==-1)
	{
		throw "栈空";
	}
	return data[topPointer];
}

template <class T>
bool SeqStack<T>::empty()
{
	if(topPointer==-1)
	{
		return true;
	}
	return false;
}

#endif


测试文件:SStackTest.cpp

#include<iostream>
#include "SeqStack.h"
using namespace std;

int main()
{
	int tmp = 0;
	SeqStack<int> *astack = new SeqStack<int>;
	
	cout<<"main"<<endl;
	
	//将10, 20, 30 依次推入栈中
	astack->push(10);
    astack->push(20);
    astack->push(30);
    
    // 将“栈顶元素”赋值给tmp,并删除“栈顶元素”
    tmp = astack->pop();
    cout<<"tmp="<<tmp<<endl;
    
    // 只将“栈顶”赋值给tmp,不删除该元素
    tmp = astack->top();
    cout<<"tmp="<<tmp<<endl;
    
    astack->push(40);
    
    while(!astack->empty())
    {
    	tmp = astack->pop();
    	cout<<"tmp="<<tmp<<endl;
	}
	return 0;
}


链栈

链栈结构实现的头文件:LinkStack.h

#ifndef LinkStack_byNim
#define LinkStack_byNim

#include<iostream>
using namespace std;

template<class T>
struct Node
{
	T data;	//数据域 
	Node *next;	//指针域 
};

template<class T>
class LinkStack
{
	private:
		Node<T> *topPointer;
	public:
		LinkStack();
		~LinkStack();
		
		void push(T e);
		T pop();
		T top();
		
		bool empty();
};

template<class T>
LinkStack<T>::LinkStack()
{
	topPointer=new Node<T>;
	topPointer->next=NULL;
}	

template<class T>	
LinkStack<T>::~LinkStack()
{
	delete topPointer;
}

template<class T>
void LinkStack<T>::push(T e)
{
	Node <T> *aNode;
	aNode=new Node<T>;
	aNode->data=e;
	aNode->next=topPointer;
	topPointer=aNode;
}

template<class T>
T LinkStack<T>::pop()
{
	if(topPointer==NULL)
		throw "下溢";
	Node <T> *p;
	p=topPointer;
	T rtndata = topPointer->data;
	topPointer=topPointer->next;
	delete p;
	return rtndata;
}

template<class T>
T LinkStack<T>::top()
{
	if(topPointer==NULL)
		throw "Empty";
	return topPointer->data;
}

template<class T>
bool LinkStack<T>::empty()
{
	if(topPointer==NULL)
		return true;
	return false;
}

#endif


测试文件:LStackTest.cpp

#include<iostream>
#include "LinkStack.h"
using namespace std;

int main()
{
	string tmp;
	LinkStack<string> *astack = new LinkStack<string>;
	
	cout<<"main"<<endl;
	
		//将"cat"、"dog"、"pig"依次推入栈中
	astack->push("cat");
    astack->push("dog");
    astack->push("pig");
    
    // 将“栈顶元素”赋值给tmp,并删除“栈顶元素”
    tmp = astack->pop();
    cout<<"tmp="<<tmp<<endl;
    
    // 只将“栈顶”赋值给tmp,不删除该元素
    tmp = astack->top();
    cout<<"tmp="<<tmp<<endl;
    
    astack->push("duck");
    
    while(!astack->empty())
    {
    	tmp = astack->pop();
    	cout<<"tmp="<<tmp<<endl;
	}
	return 0;
}

STL中自带的“栈”

头文件:#include <stack>


测试文件:StackTest.cpp

#include<iostream>
#include<stack>
using namespace std;

int main()
{
	int tmp = 0;
	stack<int> *astack = new stack<int>;
	
	cout<<"main"<<endl;
	
	//将10, 20, 30 依次推入栈中
	astack->push(10);
    astack->push(20);
    astack->push(30);
    
    // 删除“栈顶元素”,pop操作不返回栈顶数据 
    astack->pop();
    cout<<"tmp="<<tmp<<endl;
    
    // 只将“栈顶”赋值给tmp,不删除该元素
    tmp = astack->top();
    cout<<"tmp="<<tmp<<endl;
    
    astack->push(40);
    
    while(!astack->empty())
    {
    	tmp = astack->top();
    	cout<<"tmp="<<tmp<<endl;
    	astack->pop();
	}
	return 0;
}

注意:STL中自带的stack的pop操作不返回栈顶元素,只进行删除动作


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先我们需要明确什么是 N 皇后问题:在一个 N*N 的棋盘上放置 N 个皇后,使得它们互相之间不能攻击到对方,即任意两个皇后都不能处于同一行、同一列或同一斜线上。 使用的方法解决 N 皇后问题,可以采用回溯法。我们可以将每一行的皇后的列编号作为一个中的元素,从第一行开始,依次向下放置皇后,并且保证每一行的皇后不会与之前的皇后发生冲突。如果当前行无法放置皇后,则回溯到上一行,重新选择皇后的位置。 下面是 C++ 的代码实现: ```c++ #include <iostream> #include <stack> #include <cmath> using namespace std; // 判断皇后是否冲突 bool isConflict(stack<int> s, int row, int col) { int i = 0; while (!s.empty()) { int j = s.top(); if (j == col || abs(row - i) == abs(col - j)) { return true; } s.pop(); i++; } return false; } // 解决 N 皇后问题 void nQueen(int n) { stack<int> s; int row = 0, col = 0; while (row < n) { while (col < n) { if (!isConflict(s, row, col)) { s.push(col); col = 0; break; } col++; } if (s.size() == row) { if (row == n - 1) { // 打印解 cout << "Solution: "; while (!s.empty()) { cout << s.top() << " "; s.pop(); } cout << endl; } else { row++; col = 0; } } else { col = s.top() + 1; s.pop(); row--; } } } int main() { int n = 4; nQueen(n); return 0; } ``` 这里我们定义了两个函数: - `isConflict`:判断当前位置是否与之前的皇后冲突。 - `nQueen`:解决 N 皇后问题的主函数。 在 `nQueen` 函数中,我们使用一个来保存每一行的皇后的列编号。在每一行中,我们依次枚举每一列,判断当前位置是否与之前的皇后冲突。如果当前位置可以放置皇后,则将该位置的列编号压入中,并且将列编号重置为 0,继续下一行。如果当前行无法放置皇后,则回溯到上一行,重新选择皇后的位置。 当的大小等于 N 时,说明找到了一个解,我们输出该解,并且回溯到上一行,继续寻找其他解。如果回溯到第一行仍然无法找到解,则说明不存在解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值