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;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
马踏棋盘 链表 按照老师的要求的。大家来下载吧· 但是计算算比较冗余,计算不较慢。 #include #include "conio.h" using namespace std; #define edgetype int #define vextype int #define MAX 8 typedef struct node { int vextex;//序号 struct node *next; }edgenode; typedef struct { int vextex; int x,y; edgenode *link; }vexnode; const int px[8]={1,2,2,1,-1,-2,-2,-1}; const int py[8]={2,1,-1,-2,-2,-1,1,2}; const int L=8,H=8; vexnode ga[L*H]; //图 int visited[L*H]={0}; typedef struct /*顺序的结构体类型定义*/ { int stack[L*H]; int top; }seqstack; seqstack s; void setnull(seqstack *s) /*置空-由于c语言的数组下标是从0开始的,所以置 空操作时将指针放在下标为0之前,即-1处。*/ {s->top=-1;} int empty(seqstack *s) /*判断当前是否为空*/ { if(s->toptop>L*H-1) { printf("stack overflow!\n"); /*发生上溢*/ return 0; } else { s->stack[++s->top] = x; /*指针上移,数据元素入*/ return 1; } } int pop(seqstack *s) /*弹出当前s的顶元素*/ { if(s->toptop--; return(s->stack[s->top+1]); }/*由于return语句的特点,必须先使top减1,然后再执行return语句。而此时顶元素的表示应该为s->top+1.*/ } void init() { int n; for (int i=0;i<H;i++) { for (int j=0;j<L;j++) { n=L*i+j; ga[n].vextex=n; ga[n].x=j; ga[n].y=i; ga[n].link=NULL; } } printf("\n"); for (i=0;i<L*H;i++) //列出邻接链表 { edgenode *p; for (int k=0;k<MAX;k++) { int tx=ga[i].x+px[k]; int ty=ga[i].y+py[k]; if(tx<0||ty=L||ty>=H) continue; //出界了 else //采用前插 { p=(edgenode*)malloc(sizeof(edgenode)); p->vextex=ty*L+tx; p->next=ga[i].link; ga[i].link=p; // printf("%d ",ga[i].link->vextex); } } } for (i=0;i<L*H;i++) { printf("%d ",ga[i].vextex); if (!((i+1)%L)) { printf("\n"); } } } void show() //打印邻接表 { int i; printf("\n"); for (i=0;i",ga[i].vextex); edgenode *p; p=(edgenode*)malloc(sizeof
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值