栈 (顺序栈)的系列函数

stack.h和stack.c部分是void *即万能模板部分

main.c

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

#include "stack.h"
#include "SeqStack.h"

void show_menu(void){
	printf("******栈功能测试界面******\n");
	printf("*** 1.栈压入元素 \n");
	printf("*** 2.栈弹出元素 \n");
	printf("*** 3.查看栈顶元素 \n");
	printf("*** 4.栈是否为空 \n");
	printf("*** 5.栈是否满了 \n");
	printf("*** 6.栈里面元素遍历 \n");
	printf("*** 0.销毁 \n");
	printf(">>>>");
}

void print(const void *pv){
	const int *p = (const int *)pv;
	printf("%d  ",*p);
}

void test_stack(void){
	printf("请输入要创建栈的容量大小:");
	size_t cap = 0;
	scanf("%u",&cap);
	Stack s;
	stack_init(&s,cap,sizeof(int));
	int ret = 0;
	int data = 0;
	while(true){
		show_menu();
		int opt = 0;
		scanf("%d",&opt);
		switch(opt){
			case 1:
				printf("请输入要压入到栈的元素:");
				scanf("%d",&data);
				ret = stack_push(&s,&data);
				if(ret == -1){
					printf("压入失败!  栈满了!\n");
				}else{
					printf("压入成功!\n");
				}
				break;
			case 2:
				data = 0;
				ret = stack_pop(&s,&data);
				if(ret == -1){
					printf("弹出失败!  栈已空!\n");
				}else{
					printf("弹出成功,元素为:%d\n",data);
				}
				break;
			case 3:
				data = 0;
				ret = stack_peek(&s,&data);
				if(ret == -1){
					printf("查看栈顶元素失败!  栈已空!\n");
				}else{
					printf("栈顶元素为:%d\n",data);
				}	
				break;			
			case 4:
				if(stack_empty(&s)){
					printf("栈空空如也!\n");
				}else{
					printf("栈中有数据!\n");
				}
				break;
			case 5:
				if(stack_full(&s)){
					printf("栈满!\n");
				}else{
					printf("栈没满,还有空间存储数据!\n");
				}
				break;
			case 6:
				stack_travel(&s,print);
				printf("\n");
				break; 
			case 0:
				stack_destroy(&s);
				return;
		}
	}
}

void show(int col){
	printf("%d ",col);
}
#define QUEENS 8 
int eigth_queen(void){
	SeqStack stack;
	seq_stack_init(&stack,QUEENS);
	
	int col = 0;//每一行都是从0位置开始探索 
	size_t cnt = 0;//记录总共有几种摆放方法
	while(true){
		//当前行 col位置摆放一个皇后
		if(!attack(&stack,col)){//不被攻击 
			seq_stack_push(&stack,col);
			if(seq_stack_full(&stack)){
				cnt++;
				seq_stack_travel(&stack,show);
				printf("\n");
				do{
					seq_stack_pop(&stack,&col);
				}while(col+1>=QUEENS);
				col++;
				continue;
			}
			col = 0;// 摆放了一个之后   下一行从0开始探索 
		}else{
			while(col+1>=QUEENS){
				seq_stack_pop(&stack,&col);
				if(seq_stack_empty(&stack) && col==QUEENS-1){
					seq_stack_destroy(&stack);
					return cnt;
				}
			}
			++col;
		} 
	} 
}

SeqStack gs; 
//num分解成cnt个正整数之和 
void fj(int num,int cnt){//递归  num要分解成cnt个数之和   1   num-1分解成cnt-1个数之和 
	//num 分成cnt个数之和   x   num-x 分成cnt-1个数之和 
	if(num < cnt){
		return;
	}
	if(cnt == 1){
		int top = 0;
		seq_stack_top(&gs,&top);
		if(seq_stack_empty(&gs)||num>=top){
			seq_stack_push(&gs,num);
			printf("%d = ",sum(&gs));
			seq_stack_travel(&gs,show);
			printf("\n");
			seq_stack_pop(&gs,&top);
		}
		return;
	}
	int x;
	for(x=1;num-x>=cnt-1;x++){
		int top = 0;
		seq_stack_top(&gs,&top);
		if(seq_stack_empty(&gs)||x>=top){			
			seq_stack_push(&gs,x);
			fj(num-x,cnt-1);
			seq_stack_pop(&gs,&top);
		}
	}
} 
void fenjie(int num){
	seq_stack_init(&gs,num);
	//num分解成若干个数之和 
	int i;
	for(i=num;i>1;i--){
		fj(num,i);
	}
	seq_stack_destroy(&gs);
}
int main(int argc, char *argv[]) {
	//test_stack();
	//int cnt = eigth_queen();
	//printf("All:%d\n",cnt);
	printf("请输入一个正整数:");
	int num = 0;
	scanf("%d",&num);
	fenjie(num);
	return 0;
}

SeqStack.h

#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__

SeqStack.c

#include "SeqStack.h"

int seq_stack_init(SeqStack* ps,size_t cap){
	ps->base = malloc(cap * sizeof(int));//栈的申请动态内存因为结构体中是只有base要申请,所以是申请cap*sizeof(int),
	//前面的单向链表是struct,因为是给一整个头结点申请内存,头结点也是结构体类型 
	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->base+ps->size*ps->elemSize
	ps->size++;
	return 0;
}
int seq_stack_pop(SeqStack *ps,int *pdata){
	if(seq_stack_empty(ps)){
		return -1;
	}
	*pdata = ps->base[ps->size];
	--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;
}


stack.h

#ifndef _STACK_H__
#define _STACK_H__

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

//栈  顺序栈 
typedef struct Stack{
	void *base;        //数据存储的起始位置
	size_t cap;        //容量   不进行扩容    
	size_t size;       //栈里面数据元素的个数
	size_t elemSize;   //元素的字节大小 
}Stack;
//Stack s;   &s
int stack_init(Stack *ps,size_t cap,size_t elemSize);
//压入数据  只能从栈顶方向压入 
int stack_push(Stack *ps,const void *pdata); 
//弹出数据 弹出的是栈顶的元素
int stack_pop(Stack *ps,void *pdata);
//栈是否为空
bool stack_empty(Stack *ps);
//栈是否满
bool stack_full(Stack *ps);
//查看栈顶元素  只查看,不删除
int stack_peek(Stack *ps,void *pdata);
//遍历  栈底 ---> 栈顶     栈顶--->栈底 
void stack_travel(Stack *ps,void (*travel)(const void *));
//销毁
void stack_destroy(Stack *ps); 


#endif //_STACK_H__

stack.c

#include "stack.h"
/*
typedef struct Stack{
	void *base;        //数据存储的起始位置
	size_t cap;        //容量   不进行扩容    
	size_t size;       //栈里面数据元素的个数
	size_t elemSize;   //元素的字节大小 
}Stack;
*/
//Stack s;   &s
int stack_init(Stack *ps,size_t cap,size_t elemSize){
	ps->base = malloc(cap * elemSize);
	if(ps->base == NULL){
		return -1;
	}
	ps->cap = cap;
	ps->size = 0;
	ps->elemSize = elemSize;
	return 0;
}
//栈是否为空
bool stack_empty(Stack *ps){
	return ps->size == 0;
}
//栈是否满
bool stack_full(Stack *ps){
	return ps->size >= ps->cap;
}

//压入数据  只能从栈顶方向压入 
int stack_push(Stack *ps,const void *pdata){
	if(stack_full(ps)){
		return -1;
	}
	//ps->base[ps->size] = *pdata;  //int ps->base[ps->size++] = data;
	memcpy(ps->base+ps->size*ps->elemSize,pdata,ps->elemSize);
	++(ps->size);
	return 0;
}
//弹出数据 弹出的是栈顶的元素
int stack_pop(Stack *ps,void *pdata){
	if(stack_empty(ps)){
		return -1;
	}
	--(ps->size);// data = ps->base[--ps->size];
	memcpy(pdata,ps->base+ps->size*ps->elemSize,ps->elemSize);
	return 0;
}

//查看栈顶元素  只查看,不删除
int stack_peek(Stack *ps,void *pdata){
	if(ps->size == 0){
		return -1;
	}
	memcpy(pdata,ps->base+(ps->size-1)*ps->elemSize,ps->elemSize);
	return 0;
}
//遍历  栈底 ---> 栈顶     栈顶--->栈底 
void stack_travel(Stack *ps,void (*travel)(const void *)){
	size_t i;
	for(i=0;i<ps->size;i++){
		travel(ps->base+i*ps->elemSize);
	}
}
//销毁
void stack_destroy(Stack *ps){
	if(ps->base != NULL){
		free(ps->base);
		ps->base = NULL;
		ps->elemSize = 0;
		ps->size = 0;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值