图论算法(队列 栈)

本文介绍了图的邻接矩阵数据结构及其操作,包括初始化、销毁、显示图、插入和删除顶点及边。此外,还详细讲解了深度优先遍历和广度优先遍历的实现,并提供了最小生成树的Prim和Kruskal算法,以及拓扑排序和关键路径计算。代码示例中还包括了各种路径查找算法,如Dijkstra、Bellman-Ford和SPFA。
摘要由CSDN通过智能技术生成
#ifndef _ADJ_GRAPH_H__
#define _ADJ_GRAPH_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "queue.h"
typedef struct ArcNode{//弧结点   
	int adjvex;              //弧头  边  邻接点所对应的下标位置 
	int weight;              //权重  边的信息 
	struct ArcNode *next;    //下一个弧结点 
}ArcNode; 

typedef struct VNode{//顶点  
	char data;                  //顶点元素  
	struct ArcNode *firstarc;   //第一个弧结点   从顶点出发所有的边 
}VNode;

typedef enum GraphKind{DG,DN,UDG,UDN}GraphKind; 

typedef struct ALGraph{
	struct VNode *vexs;         //所有顶点  数组 
	int vexnum;                 //顶点数
	int arcnum;                 //弧、边条数
	GraphKind kind;             //图的类型 
}ALGraph;

typedef struct Edge{//边  
	char vbeg;         //起始点 
	char vend;         //结束点 
	int weight;        //权重 
}Edge;

typedef struct Path{//边 
	int ibeg;           //起始点下标 
	int iend;           //终点下标
	int weight;         //权重 
}Path; 
//ALGraph g;
int graph_init(ALGraph *pg,char vexs[],size_t vexnum,
        Edge edges[],size_t arcnum,GraphKind kind); //初始化
        
void graph_destroy(ALGraph *pg); //销毁
void graph_show(ALGraph *pg);//打印
//int graph_get_index(ALGraph *pg,char key);//通过顶点的值 查找顶点所在的下标
int graph_insert_vertex(ALGraph *pg,char key);//插入一个顶点
int graph_delete_vextex(ALGraph *pg,char key);//删除一个顶点
int graph_insert_edge(ALGraph *pg,Edge edge);//插入一条边
int graph_delete_edge(ALGraph *pg,Edge edge);//删除一条边 

void dfs_travel(ALGraph *pg,void (*travel)(char));//深度优先遍历
void bfs_travel(ALGraph *pg,void (*travel)(char));//广度优先遍历
void prim(ALGraph *pg); //最小生成树
void kruskal(ALGraph *pg);//最小生成树
int topo_sort(ALGraph *pg,struct Queue *que);//拓扑排序
int critical_path(ALGraph *pg);//关键路径
int dfs_min_path(ALGraph *pg,char beg,char end);// 递归求最短路径
void floyd(ALGraph *pg);//最短路径 多个点到多个点最短距离
int dijsktra(ALGraph *pg,char key);//求一个点到多个点的最短距离
int bellman_ford(ALGraph *pg,char key);//和dijsktra寻找类似 但有对负环的判定
int SPFA(ALGraph *pg,char key);//对bellman_ford的算法优化

#endif //_ADJ_GRAPH_H__
#include "adjgraph.h"
#include "queue.h"
#include "stack.h"

static int graph_get_index(ALGraph *pg,char key){//通过顶点的值 查找顶点所在的下标
	int i;
	for(i=0;i<pg->vexnum;i++){
		if(pg->vexs[i].data == key){
			return i;
		}
	}
	return -1;
}
static ArcNode *graph_create_arcnode(int adjvex,int weight,ArcNode *next){
	ArcNode *node = (struct ArcNode*)malloc(sizeof(ArcNode));
	if(node!=NULL){
		node->adjvex = adjvex;
		node->weight = weight;
		node->next = next;
	}
	return node;
} 

//ALGraph g;
int graph_init(ALGraph *pg,char vexs[],size_t vexnum,
        Edge edges[],size_t arcnum,GraphKind kind){
    pg->vexs = (VNode *)malloc(sizeof(VNode)*vexnum);
    if(pg->vexs==NULL)
    	return -1;
    pg->vexnum = vexnum;
    int i;
    for(i=0;i<vexnum;i++){
    	pg->vexs[i].data = vexs[i];//顶点的值 
    	pg->vexs[i].firstarc = NULL;//顶点没有边 
	}
    pg->arcnum = 0;
    pg->kind = kind;
    for(i=arcnum-1;i>=0;--i){
		graph_insert_edge(pg,edges[i]); //插入一条边 
	}
	return 0; 
} 
        
void graph_destroy(ALGraph *pg){
	int i;
	for(i=0;i<pg->vexnum;i++){
		ArcNode *node = pg->vexs[i].firstarc,*next;
		while(node != NULL){
			next = node->next;
			free(node);
			node = next;
		}
	}
	free(pg->vexs);
	pg->vexs = NULL;
	pg->vexnum = 0;
	pg->arcnum = 0;	
}
void graph_show(ALGraph *pg){
	int i;
	for(i=0;i<pg->vexnum;i++){
		if(pg->vexs[i].data != '\0'){
			printf("%c :",pg->vexs[i].data);
			ArcNode *node = pg->vexs[i].firstarc;
			for(;node!=NULL;node=node->next){
				printf(" [%d]%c",node->weight,pg->vexs[node->adjvex].data);
			}
			printf("\n");
		}
	}
}

int graph_insert_vertex(ALGraph *pg,char key){//插入一个顶点
	if(graph_get_index(pg,key)>=0){//key作为顶点的值已经有了 
		return -1;
	}
	VNode *node = realloc(pg->vexs,sizeof(VNode)*(pg->vexnum+1));
	if(node==NULL){
		return -2;
	} 
	pg->vexs = node;
	pg->vexs[pg->vexnum].data = key;
	++pg->vexnum;
	return 0;
}
int graph_delete_vextex(ALGraph *pg,char key){//删除一个顶点
	int index = graph_get_index(pg,key);
	if(index == -1){
		return -1;
	}
	pg->vexs[index].data = '\0';
	ArcNode *node = pg->vexs[index].firstarc,*next;
	while(node!=NULL){
		next = node->next;
		free(node);
		node = next;
	}
	int i;
	for(i=0;i<pg->vexnum;i++){
		if(pg->vexs[i].data != '\0'){
			ArcNode **pnode = &(pg->vexs[i].firstarc);
			while(*pnode != NULL){
				if((*pnode)->adjvex == index){
					node = *pnode;
					*pnode = node->next;
					free(node);
					break;
				}
				pnode = &(*pnode)->next;
			}
		}
	}
	return 0;
}
int graph_insert_edge(ALGraph *pg,Edge edge){//插入一条边 
	int ibeg = graph_get_index(pg,edge.vbeg);//获取边起始顶点下标 
	int iend = graph_get_index(pg,edge.vend);//获取边结束顶点下标 
	if(ibeg==-1 || iend==-1)//无效边 
		return -1; 
	//前插法  新的边插入到最前面   
	//判断一条边是否存在 如果存在了 不插了 
	ArcNode *node = pg->vexs[ibeg].firstarc;
	while(node!=NULL){
		if(node->adjvex == iend){// ibeg->iend边已经存在了! 
			return -3;
		}
		node = node->next;
	} 
	pg->vexs[ibeg].firstarc = 
		graph_create_arcnode(iend,edge.weight,pg->vexs[ibeg].firstarc); 
	if(pg->vexs[ibeg].firstarc==NULL){
		return -2;
	} 	
	if(pg->kind == UDG || pg->kind == UDN){
		pg->vexs[iend].firstarc = 
			graph_create_arcnode(ibeg,edge.weight,pg->vexs[iend].firstarc);
		if(pg->vexs[iend].firstarc==NULL){
			node = pg->vexs[ibeg].firstarc;
			pg->vexs[ibeg].firstarc = node->next;
			free(node);
			return -2;
		}
	}
	++pg->arcnum;
	return 0;
}

int graph_delete_edge(ALGraph *pg,Edge edge){//删除一条边 
	int ibeg = graph_get_index(pg,edge.vbeg); 
	int iend = graph_get_index(pg,edge.vend);
	if(ibeg == -1 || iend == -1){
		return -1;
	}
	ArcNode **pnode = &(pg->vexs[ibeg].firstarc);
	ArcNode *node;
	bool isdel = false;
	while(*pnode!=NULL){
		if((*pnode)->adjvex == iend){
			node = *pnode;
			*pnode = node->next;
			free(node);
			isdel = true;
			break;
		}
		pnode = &(*pnode)->next; 
	}
	if(pg->kind == UDG||pg->kind == UDN){
		pnode = &(pg->vexs[iend].firstarc);
		while(*pnode!=NULL){
			if((*pnode)->adjvex == ibeg){
				node = *pnode;
				*pnode = node->next;
				free(node);
				break;
			}
		}
	}
	--pg->arcnum;
	return isdel?0:-2;
}
//遍历index顶点
static void DFS(ALGraph *pg,int index,bool visited[],void (*travel)(char)){
	visited[index] = true;//遍历index顶点  index已经被遍历 
	travel(pg->vexs[index].data);//输出  
	ArcNode *node = pg->vexs[index].firstarc;//遍历index顶点的邻接点 
	while(node!=NULL){
		if(!visited[node->adjvex]){//邻接点没有被遍历  
			DFS(pg,node->adjvex,visited,travel);
		}
		node = node->next;
	} 
}

void dfs_travel(ALGraph *pg,void (*travel)(char)){
	//定义一个数组来标识对应位置的顶点是否被遍历过了 
	bool visited[pg->vexnum];
	int i;//memset(visisted,0,sizeof(visited));
	for(i=0;i<pg->vexnum;i++)
		visited[i] = false;//初始化false,都没有被遍历过 
	for(i=0;i<pg->vexnum;i++)//从第一个顶点逐个开始遍历 
		if(!visited[i])//i顶点没有被遍历过 
			DFS(pg,i,visited,travel);//去遍历顶点i(下标为i的顶点) 
}
void bfs_travel(ALGraph *pg,void (*travel)(char)){
	Queue que;//辅助队列  
	queue_init(&que,pg->vexnum);
	bool visited[pg->vexnum];
	int i;
	for(i=0;i<pg->vexnum;i++)
		visited[i] = false;
	for(i=0;i<pg->vexnum;i++){//非连通图考虑  遍历所有顶点 
		if(!visited[i]){
			visited[i] = true;
			queue_push(&que,i);
			while(!queue_empty(&que)){
				int v = queue_pop(&que);
				travel(pg->vexs[v].data);
				ArcNode *node = pg->vexs[v].firstarc;
				for(;node!=NULL;node=node->next){//直接遍历所有的邻接点 
					if(!visited[node->adjvex]){
						visited[node->adjvex] = true; 
						queue_push(&que,node->adjvex);
					}
				}
			}
		}
	}
	queue_destroy(&que);
}
#define MAX_INT (~(1<<31))
void prim(ALGraph *pg){//O(|V|*|V|+|E|)) 
	int dist[pg->vexnum]; //保存未加入到生成树的所有顶点到达生成树中的距离
	int begv[pg->vexnum]; //begv[i]记录到顶点i的最短距离的边的开始顶点 
	//dist[i] 表示 到顶点i的距离  dist[i]==0 表示i顶点已经在生成树中了
	int i,j;
	for(i=0;i<pg->vexnum;i++){
		dist[i] = MAX_INT; //最大值   表示一开始到生成树的距离无穷大 
		begv[i] = -1; 
	}
	int curr = 0; 
	for(i=0;i<pg->vexnum-1;i++){//循环pg->vexnum-1次   
		dist[curr] = 0;//curr顶点加入到生成树中
		ArcNode *node = pg->vexs[curr].firstarc;
		//更新未加入到生成树中的所有顶点到生成树中顶点的距离  
		for(;node!=NULL;node=node->next){
			//node->adjvex不在生成树中  它到生成树的距离比之前小 
			if(dist[node->adjvex]!=0 && node->weight < dist[node->adjvex]){
				dist[node->adjvex] = node->weight;
				begv[node->adjvex] = curr;//该距离是从curr到node->adjvex顶点 
			}
		}
		int min = 0;
		for(j=1;j<pg->vexnum;j++){//选取一条到生成树中最小的边 
			if((dist[j]!=0&&dist[j]<dist[min])||dist[min]==0){
				min = j;
			}
		} 
		printf("%c -[%d]-> %c\n",pg->vexs[begv[min]].data,dist[min],pg->vexs[min].data);
		curr = min;
	} 
}
int comp_path(const void *v1,const void *v2){
	const Path *pa = (const Path*)v1;
	const Path *pb = (const Path*)v2;
	return pa->weight - pb->weight;
}

//与curr顶点相连的最开始的顶点 
static int find_src(int flag[],int curr){
	while(flag[curr]!=curr){
		curr = flag[curr];
	} 
	return curr;
}
void kruskal(ALGraph *pg){//O(|V|+|E|log|E|)
	Path path[pg->arcnum];
	int j = 0;
	int i;
	for(i=0;i<pg->vexnum;i++){//O(|E|+|V|) 
		ArcNode *node = pg->vexs[i].firstarc;
		for(;node!=NULL;node = node->next){
			//i  node->adjvex  node->weight
			if(i>node->adjvex && (pg->kind==UDG||pg->kind==UDN)){
				continue;
			}
			path[j].ibeg = i;
			path[j].iend = node->adjvex;
			path[j].weight = node->weight;
			++j;
		}
	} 
	qsort(path,pg->arcnum,sizeof(Path),comp_path);//O(|E|log|E|)
	int cnt = 0;//记录选取的边数 
	int flag[pg->vexnum];
	for(i=0;i<pg->vexnum;i++)
		flag[i] = i;
	
	for(i=0;i<pg->arcnum&&cnt<pg->vexnum-1;i++){//O(|V|)
		int src1 = find_src(flag,path[i].ibeg);
		int src2 = find_src(flag,path[i].iend);
		if(src1!=src2){//说明ibeg,iend 连接的边 选取之后 不会构成回路 
			printf("%c -[%d]-> %c\n",pg->vexs[path[i].ibeg].data,path[i].weight,
				pg->vexs[path[i].iend].data);
			cnt++;
			flag[src1] = src2;
		}
	}
}

int topo_sort(ALGraph *pg,Queue *que){
	Queue q;
	queue_init(&q,pg->vexnum);
	queue_init(que,pg->vexnum);
	int in[pg->vexnum];//记录所有顶点的入度
	int i;
	for(i=0;i<pg->vexnum;i++)
		in[i] = 0;
	//统计每个顶点的入度 
	for(i=0;i<pg->vexnum;i++){
		ArcNode *node = pg->vexs[i].firstarc;
		while(node!=NULL){
			in[node->adjvex]++;
			node = node->next;
		}
	} 
	for(i=0;i<pg->vexnum;i++){
		if(in[i]==0){//入度为0 
			queue_push(que,i); 
			queue_push(&q,i);
		}
	} 
	while(!queue_empty(&q)){
		int vex = queue_pop(&q);
		//printf("%c ",pg->vexs[vex].data);
		ArcNode* node = pg->vexs[vex].firstarc;
		for(;node!=NULL;node=node->next){
			--in[node->adjvex];
			if(in[node->adjvex]==0){
				queue_push(que,node->adjvex);
				queue_push(&q,node->adjvex);
			}
		}
	}
	//printf("\n");
	queue_destroy(&q);
	return queue_full(que)?0:-1;
}  
int critical_path(ALGraph *pg){
	Queue que;
	int ret = topo_sort(pg,&que);
	if(ret != 0){
		return -1; 
	}
	SeqStack  stack;
	seq_stack_init(&stack,pg->vexnum);
	int ev[pg->vexnum];//事件最早发生时间  
	int el[pg->vexnum];//事件最晚发生时间 
	int i;
	for(i=0;i<pg->vexnum;i++){
		ev[i] = 0;
		el[i] = 0;
	}
	int m = 0;
	//事件的最早发生时间 
	while(!queue_empty(&que)){
		int vex = queue_pop(&que);//弹出一个顶点的下标
		seq_stack_push(&stack,vex);
		ArcNode *node = pg->vexs[vex].firstarc;
		for(;node!=NULL;node=node->next){
			if(ev[node->adjvex] < ev[vex]+node->weight){
				ev[node->adjvex] = ev[vex]+node->weight;
				m = ev[node->adjvex];//最晚发生时间最设置成最早发生时间 
			}
		} 
	}
	for(i=0;i<pg->vexnum;i++){
		el[i] = m;
	}
	//事件的最晚发生时间
	while(!seq_stack_empty(&stack)){
		int vex = 0;
		seq_stack_pop(&stack,&vex);
		ArcNode *node = pg->vexs[vex].firstarc;
		for(;node!=NULL;node=node->next){
			if(el[vex] > el[node->adjvex]-node->weight){
				el[vex] = el[node->adjvex]-node->weight;
			}
		} 
	} 
	//活动的最早发生时间 和 最晚发生时间  时间余量 
	for(i=0;i<pg->vexnum;i++){
		ArcNode *node = pg->vexs[i].firstarc;
		for(;node!=NULL;node=node->next){
			int ae = ev[i];// <i,node->adjvex> 活动的最早开始时间 
			int al = el[node->adjvex] - node->weight;
			if(ae == al){
				printf("%c -[%d]-> %c\n",
				pg->vexs[i].data,node->weight,pg->vexs[node->adjvex].data);
			} 
		}
	}
	queue_destroy(&que);
	seq_stack_destroy(&stack);
	return 0;
}
//ibeg,iend的最小距离  现在到了icurr点  currpath现在已经经过了多长的距离 
void dfs_path(ALGraph *pg,int icurr,int iend,
	int *pminpath,int currpath,bool visited[]){
	if(icurr==iend){
		if(currpath < *pminpath){
			*pminpath = currpath;
		}
		return;
	}
	ArcNode *node = pg->vexs[icurr].firstarc;
	for(;node!=NULL;node=node->next){
		if(!visited[node->adjvex] && currpath + node->weight < *pminpath){
			visited[node->adjvex] = true;
			dfs_path(pg,node->adjvex,iend,pminpath,currpath+node->weight,visited);
			visited[node->adjvex] = false;
		}
	}
}
//求beg,end顶点的最短路径 
int dfs_min_path(ALGraph *pg,char beg,char end){
	int ibeg = graph_get_index(pg,beg);
	int iend = graph_get_index(pg,end);
	if(ibeg==-1||iend==-1)
		return -1;
	if(ibeg==iend)
		return 0;
	int minpath = MAX_INT;//记录最短路径的值 
	int currpath = 0; //找的过程中,经过的多长距离  
	bool visited[pg->vexnum];
	int i;
	for(i=0;i<pg->vexnum;i++)
		visited[i] = false;
	visited[ibeg] = true;	 
	dfs_path(pg,ibeg,iend,&minpath,0,visited);
	return minpath;
}

void floyd(ALGraph *pg){
	int vn = pg->vexnum;
	int path[vn][vn];
	int i,j,k;
	for(i=0;i<vn;i++){
		for(j=0;j<vn;j++)
			path[i][j] = MAX_INT;
	}
	for(i=0;i<vn;i++){
		ArcNode *node = pg->vexs[i].firstarc;
		for(;node!=NULL;node=node->next){
			path[i][node->adjvex] = node->weight;
		}
	} 
	for(k=0;k<vn;k++){
		for(i=0;i<vn;i++){
			for(j=0;j<vn;j++){
				int x = path[i][k];
				int y = path[k][j];
				int z = path[i][j];
				if(i!=j&&k!=i&&k!=j&&x!=MAX_INT&&y!=MAX_INT&&x+y<z){ 
					path[i][j] = x+y;
				}
			}
		}
	}
	for(i=0;i<vn;i++){
		for(j=0;j<vn;j++){
			if(path[i][j]==MAX_INT){
				printf("--- ");
			}else{
				printf("%3d ",path[i][j]);
			}
		}
		printf("\n");
	}
}

int dijsktra(ALGraph *pg,char key){
	int index = graph_get_index(pg,key);
	if(index==-1)
		return -1;
	int vn = pg->vexnum;
	int path[vn];//index到其它点的距离 
	bool visited[vn];//每次最短距离的点进行松弛 
	int i,j;
	for(i=0;i<vn;i++){
		path[i] = MAX_INT;
		visited[i] = false;
	}
	path[index] = 0;
	int min = 0;
	for(i=0;i<vn;i++){
		min = 0;
		for(j=0;j<vn;j++){
			if(visited[min]||(!visited[j] && path[min]>path[j])){
				min = j;
			}
		}
		visited[min] = true;
		ArcNode *node = pg->vexs[min].firstarc;
		for(;node!=NULL;node=node->next){
			if(path[node->adjvex] > path[min]+node->weight){
				path[node->adjvex] = path[min]+node->weight;
			}
		}
	}
	printf("%c:",pg->vexs[index].data);
	for(i=0;i<vn;i++){
		printf("%d ",path[i]);
	}
	printf("\n");
}

int bellman_ford(ALGraph *pg,char key){
	int index = graph_get_index(pg,key);
	if(index==-1)
		return -1;
	int vn = pg->vexnum;
	int path[vn];
	int i,j;
	for(i=0;i<vn;i++)
		path[i] = MAX_INT;
	path[index] = 0;
	bool change = false;
	for(i=1;i<vn;i++){//进行n-1次松驰 
		change = false;
		for(j=0;j<vn;j++){
			ArcNode *node = pg->vexs[j].firstarc;
			for(;node!=NULL;node=node->next){
				if(path[j]!=MAX_INT && path[node->adjvex] > path[j]+node->weight){
					path[node->adjvex] = path[j]+node->weight;
					change = true;
				}
			}
		}
		if(!change){
			break;
		}
	}
	printf("%c:",pg->vexs[index].data);
	for(i=0;i<vn;i++){
		printf("%d ",path[i]);
	}
	printf("\n");
	change = false;
	for(j=0;j<vn;j++){//第n次松弛 
		ArcNode *node = pg->vexs[j].firstarc;
		for(;node!=NULL;node=node->next){
			if(path[j]!=MAX_INT && path[node->adjvex] > path[j]+node->weight){
				path[node->adjvex] = path[j]+node->weight;
				change = true;
				return 1;//负环 
			}
		}
	}
	return 0; 
}

int SPFA(ALGraph *pg,char key){
	int index = graph_get_index(pg,key);
	if(index == -1)
		return -1;
	int vn = pg->vexnum;
	int path[vn];
	int times[vn];
	int i;
	for(i=0;i<vn;i++){	
		path[i] = MAX_INT;
		times[i] = 0;
	}
	Queue que;
	queue_init(&que,vn);
	path[index] = 0;
	queue_push(&que,index);
	times[index]++;
	while(!queue_empty(&que)){
		int v = queue_pop(&que);
		ArcNode *node = pg->vexs[v].firstarc;
		for(;node!=NULL;node=node->next){
			if(path[v]!=MAX_INT && path[node->adjvex] > path[v]+node->weight){
				path[node->adjvex] = path[v]+node->weight;
				if(queue_elem_same(&que,node->adjvex)==0){
					queue_push(&que,node->adjvex);
					times[node->adjvex]++;
					if(times[node->adjvex]==vn){
						queue_destroy(&que);
						return 1;
					}
				}
			}
		}
	}
	
	printf("%c:",pg->vexs[index].data);
	for(i=0;i<vn;i++){
		printf("%d ",path[i]);
	}
	printf("\n");
	return 0;
	
}
#ifndef _QUEUE_H__
#define _QUEUE_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "adjgraph.h"

typedef struct Queue{
	int *data;
	size_t cap;   //队列最大容量
	size_t size;  //队列中元素的个数
	size_t first; //队列头的下标位置        
}Queue;

int queue_init(Queue *que,size_t cap);
bool queue_empty(Queue *que);
bool queue_full(Queue *que);
int queue_push(Queue *que,int elem);
int queue_pop(Queue *que);
int queue_first(Queue *que);
void queue_travel(Queue *que,void (*travel)(int));
void queue_destroy(Queue *que);
int queue_elem_same(Queue *que,int elem);

#endif //_QUEUE_H__


#include "queue.h"

int queue_init(Queue *que,size_t cap){
	que->data = (int*)malloc(cap*sizeof(int));
	if(que->data == NULL){
		return -1;
	}
	que->cap = cap;
	que->size = 0;
	que->first = 0;
}
bool queue_empty(Queue *que){
	return que->size == 0;
}
bool queue_full(Queue *que){
	return que->size >= que->cap;
}
int queue_push(Queue *que,int elem){
	if(queue_full(que)){
		return -1;
	}
	que->data[(que->first + que->size)%que->cap] = elem;
	(que->size)++;
	return 0;
}
int queue_pop(Queue *que){
	int elem = que->data[que->first];
	que->first++;
	que->size--;
	if(que->first>=que->cap){
		que->first = 0;
	}
	return elem;
}
int queue_first(Queue *que){
	return que->data[que->first]; 
}
void queue_travel(Queue *que,void (*travel)(int)){
	size_t i;
	for(i=0;i<que->size;i++){
		travel(que->data[(que->first+i)%que->cap]);
	}
}
void queue_destroy(Queue *que){
	if(que->data!=NULL){
		free(que->data);
		que->data = NULL;
		que->size = 0;
		que->first = 0;
	}
}

int queue_elem_same(Queue *que,int elem){
	size_t i;
	for(i=0;i<que->size;i++){
		if(elem == que->data[(que->first+i)%que->cap])
			return 1;
	}	
	return 0;
}

#ifndef _SEQ_STACK_H__
#define _SEQ_STACK_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef struct SeqStack{
	int *base;
	size_t cap;
	size_t size; 
}SeqStack;

int seq_stack_init(SeqStack* ps,size_t cap);
bool seq_stack_empty(SeqStack *ps);
bool seq_stack_full(SeqStack *ps);
int seq_stack_push(SeqStack *ps,int data);
int seq_stack_pop(SeqStack *ps,int *pdata);
int seq_stack_top(SeqStack *ps,int *pdata);
void seq_stack_travel(SeqStack *ps,void (*travel)(int)); 
void seq_stack_destroy(SeqStack *ps);
bool attack(SeqStack *ps,int col);
int sum(SeqStack *ps);
int size(SeqStack *ps);

#endif //_SEQ_STACK_H__


#include "stack.h"

int seq_stack_init(SeqStack* ps,size_t cap){
	ps->base = malloc(cap * sizeof(int));
	if(ps->base==NULL)
		return -1;
	ps->cap = cap;
	ps->size = 0;
	return 0;
}
bool seq_stack_empty(SeqStack *ps){
	return ps->size == 0;
}
bool seq_stack_full(SeqStack *ps){
	return ps->size >= ps->cap;
}
int seq_stack_push(SeqStack *ps,int data){
	if(seq_stack_full(ps)){
		return -1;
	}
	ps->base[ps->size] = data;
	ps->size++;
	return 0;
}
int seq_stack_pop(SeqStack *ps,int *pdata){
	if(seq_stack_empty(ps)){
		return -1;
	}
	*pdata = ps->base[--(ps->size)];
	return 0;
}
int seq_stack_top(SeqStack *ps,int *pdata){
	if(seq_stack_empty(ps)){
		return -1;
	}
	*pdata = ps->base[ps->size-1];
	return 0;
}
void seq_stack_travel(SeqStack *ps,void (*travel)(int)){
	size_t i;
	for(i=0;i<ps->size;i++){
		travel(ps->base[i]);
	}
} 
void seq_stack_destroy(SeqStack *ps){
	if(ps->base!=NULL){
		free(ps->base);
		ps->base = NULL;
		ps->cap = 0;
		ps->size = 0;
	}
}
bool attack(SeqStack *ps,int col){// 在ps->size行,col列 探索是否可以摆放皇后 
	size_t i;
	for(i=0;i<ps->size;i++){
		//i行  ps->base[i]列 
		if(col == ps->base[i]){
			return true;//被攻击 
		} 
		if(ps->size - i == col-ps->base[i] || ps->size -i == ps->base[i]-col){
			return true;
		}
	} 
	return false;
}

int sum(SeqStack *ps){
	int s = 0;
	size_t i;
	for(i=0;i<ps->size;i++){
		s+=ps->base[i];
	}
	return s;
}
int size(SeqStack *ps){
	return ps->size;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值