C++_014_数据结构_队列和栈的STL应用

包含的内容

1.从回调函数到STL。
2.队列  queue / deque的STL库。
2.优先队列priority_queue 的STL库,大小堆方法。
4.用栈和队列的STL解决问题。
4.1. 八皇后问题。
4.2.多括号匹配问题。
4.3.马踏棋盘问题。

从回调到STL

  介绍一些回调,再列举STL的队列和栈。

C语言的回调

#include<stdio.h>
//回调方法一 
void print(int n)
{
	printf("调用 print() 输出%d\n",n);
}

void show1(int a,void (*ptr)())
{
	(*ptr)(a);//也可以直接用 ptr(a); 因为函数指针可以直接使用。
}

void print2(int s)
{
	printf("调用print2(),打印%d \n",s);
}
//回调方法二 用别名调用。 
typedef void (*funtypename)(int n);//print(int n) 和 print2() 都满足该格式.
void show2(int a,funtypename f)
{
	f=print;
	f(a);
	f=print2;
	f(a);
}
int main()
{
	show1(111,print);
	printf("*************\n"); 
	show2(22,print);
	return 0;
}
运行结构如果。

从C++的回调

#include<cstdio>
#include<queue>
#include<cstdlib>
#include<iostream>
#include<ctime>
using namespace std;

void print(int n)
{
	printf("%d print() 被调用\n",n);
}

typedef void (*callback)(int n);//和print(int )一个格式
 
void show(int n,callback f)//用typedef调用 
{
	f=print;
	f(n);
}

void show2(int n,void (*ptr)(int))//不用typedef调用 
{
	ptr(n);
}

int main()
{
	callback p;//p是函数指针.等同于下句 p2 
	void (*p2)(int n); 
	show(1111,p);
	show(1111,p2);
	show2(2222,print);
	return 0;
}
运行结果如果

C++ 类仿函数

#include <iostream>
using namespace std;
typedef void(*Fun)(void);
inline void TextFun(void)
{
	cout << "普通回调函数" << endl;
} 
class TextFunor
{
public:
	TextFunor()
	{
		cout<<"构造"<<endl;
	}
	~TextFunor()
	{
		cout<<"析构"<<endl;
	}
	void operator()(void) const
	{
		cout << "()重载函数" << endl;
	} 
};

void ForText(Fun pFun, TextFunor cFun)
{
	pFun();
	cFun();
}

int main()
{
	TextFunor cFunor;
	ForText(TextFun, cFunor);
	return 0;
}

STL的queue


STL的priority_queue


priority_queue 大小堆建立方法

    priority_queue<tyoe,container,functional>  默认大顶堆,大的在队首。默认用operator<() 比较。 

优先队列改为小堆的方法:

如int类的普通类型 用 priority_queue<int,vector<int>,greater<int>>
自定义类型,重写operator<()【故意把小于写成大于不就成小堆了吗】或重写仿函数。
重写仿函数  priority_queue<int,vector<Node>,cmp>;cmp代表比较函数,(可以是内置的greater,less,也可以是防函数)写法如下。
#include <iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;

typedef struct Node
{
	int x;
	int y;
	bool operator()(Node a,Node b)//用于下文比较的仿函数。
	{
		return a.x>b.x;
	}


	void print()
	{
		cout<<"x="<<x<<" "<<"y="<<y<<endl;
	}
	
}Node;


//在外面重载才能把 
bool operator >(Node a,Node b)//重载大于,可用greater()函数。 
{
	return a.x>b.x;
}
	
bool operator <(Node a,Node b)//优先队列默认重载小于,有了小于可用于Node的入队。 
{
	return a.x<b.x;
}


struct cmp// 这是一个外部写的仿函数。
{
	bool operator()(Node a,Node b)
	{
		return a.x>b.x;
	}
}; 


int main()
{
	priority_queue<Node,vector<Node>,greater<Node>>  a;
	//priority_queue<Node,vector<Node>,Node>  a;
	//priority_queue<Node,vector<Node>,cmp>  a; 没有重载大于就自己写仿函数这样用。 
	//priority_queue<Node,vector<Node>,less<Node>> a;
	Node b[3];
	b[0].x=b[0].y=1;
	b[1].x=b[1].y=2;
	b[2].x=b[2].y=3;
	
	a.push(b[0]);
	a.push(b[1]);
	a.push(b[2]);
	
	Node c;
	c=a.top();
	c.print();
	a.pop();
	c=a.top();
	c.print();
	return 0;
}

C++的stack


deque


用堆栈的 STL 解决问题

多括号匹配



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


//  <{>}  <>{}(<>)
int main()
{
	stack<char> a;//() [] {} <>
	char brackets[40];
	loop:
	scanf("%s",&brackets);
	
	int i=0;
	int b=true;
	
	while(brackets[i]!='\0')
	{
		switch(brackets[i])
		{
			case '(':
				{
					a.push('(');
					break;
				}
			case ')':
				{
					if(a.top()!='(')
					{
						
						b=false;
						break;
					}
					else
					a.pop();
					break;
				}
			case '[':
				{
					a.push('[');
					break;
				}
			case ']':
				{
					if(a.top()!='[')
					{
						
						b=false;
						break;
					}
					else
					a.pop();
					break;
				}
			case '{':
				{
					a.push('{');
					break;
				}
			case '}':
				{
					if(a.top()!='{')
					{
						
						b=false;
						break;
					}
					else
					a.pop();
					break;
				}
			case '<':
				{
					a.push('<');
					break;
				}
			case '>':
				{
					if(a.top()!='<')
					{
						
						b=false;
						break;
					}
					else
					a.pop();
					break;
				}
			default:
				{
					break;
				}
				
		}
		if(b==false)
		{
			break;
		}
		
		i++;
	}
	if(b)
	{
		printf("括号匹配\n");
	}
	else
	{
		printf("括号不匹配\n");
	}
	return 0;
}


8皇后


#include <iostream>
using namespace std;
int kind=0;
const int N=8;
int arr[N+1],column[N+1],Left[2*N+1],Right[2*N+1];

void tryit(int i)
{
	int j;
	for(j=1;j<=8;j++)
	{
		if(!column[j]&&!Left[i-j+8]&&!Right[i+j])
		{
			arr[i]=j;column[j]=1;Left[i-j+8]=1;Right[i+j]=1;
			if(i<8)
			{
				tryit(i+1);
			}
			else
			{
				kind++;
			}
			column[j]=Left[i-j+8]=Right[i+j]=0;
		}
	}
}
int main()
{
	tryit(1);
	printf("%d",kind);
	return 0;
}

马踏棋盘问题


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

int Next[8][2]={{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}}; 
int map[8][8]={0};

typedef struct Node
{
	int x;
	int y;
	int step;
}Node;


int main()
{
	queue<Node> a;
	Node Firstone={0,0,1};
	a.push(Firstone);
	map[0][0]=1;
	Node Nextone;
	Node Nowone;
	int count=2;
	while(!a.empty())
	{
		for(int i=0;i<8;i++)
		{
			Nextone.x=a.front().x+Next[i][0];
			Nextone.y=a.front().y+Next[i][1];
			
			if(Nextone.x<0||Nextone.y<0||Nextone.x>=8||Nextone.y>=8)
			{
				continue;
			}
			if(map[Nextone.x][Nextone.y]==0)
			{
				map[Nextone.x][Nextone.y]=count;
				Nextone.step=a.back().step+1;
				a.push(Nextone);
				count++;
			}
			
		}
		a.pop();
		
	}
	
	printf("广搜法,马踏棋盘的顺序:\n");
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			printf("%3d ",map[i][j]);
		}
		printf("\n");
	}
	return 0;
}



猜你喜欢

转载自blog.csdn.net/wang_huizhang/article/details/76099200