c语言实现任何数据类型的stack(栈)

c语言实现任何数据类型的stack(栈),第1张

因为在学快排的时候用到栈,针对上一个版本我觉得使用很不方便,所以最近有改良了下,用int,char,int*,char*,char[]数组(字符串类型)时,不用在需要强转指针后在解引用使用了。

如需更完整的解释请访问上一版本传送门

目录

完整代码

stack.h(函数声明)

stack.c(函数实现)

test.c(测试代码)

测试结果


完整代码 stack.h(函数声明)
#pragma once
#define _CRT_SECURE_NO_DEPRECATE  1
#include
#include
#include
#include
#include  
#define MAXNUM 4//初始数组大小
typedef struct stack
{
	void* _date;//指向自定义数组类型
	int  _current;//当前元素个数
	int _size;//元素最大个数
	int _type;//类型占用字节数
	void (*clear) (struct stack*);//清空stack的队列,释放内存
	void(*push)(struct stack* st, void*);//压栈,增加元素 O(1)
	void (*pop)(struct stack* st);//移除栈顶元素 O(1)
	int* (*top)(struct stack*);// 取得栈顶元素(但不删除)O(1)
	bool (*empty)(struct stack*);// 检测栈内是否为空,空为真 O(1)
	int (*size)(struct stack*);//返回stack内元素的个数 O(1)
}stack;
void Stack_clear(stack* st);//清空stack的队列,释放内存
void Stack_Push(stack* st,const void* x);// 压栈,增加元素 O(1)
void Stack_Push_char(stack* st,const char x);
void Stack_Push_Char(stack* st,const char* x);
void Stack_Push_charArray(stack* st, const char* x);
void Stack_Push_int(stack* st, const int x);
void Stack_Push_Int(stack* st, const int* x);
void Stack_pop(stack* st);//移除栈顶元素 O(1)
void* Stack_top(stack* st);// 取得栈顶元素(但不删除)O(1)
char Stack_top_char(stack* st);
char* Stack_top_Char(stack* st);
char* Stack_top_charArray(stack* st);
int Stack_top_int(stack* st);
int* Stack_top_Int(stack* st);
bool Stack_empty(stack* st);//检测栈内是否为空,空为真 O(1)
int Stack_size(stack* st);//返回stack内元素的个数 O(1)
//stack容器初始化函数,st栈的指针,n数据类型大小(字节)
void StackINIT(stack* st,char* arr, ...);

stack.c(函数实现)
#include"stack.h"
void Stack_clear(stack* st)
{
	free(st->_date);
	st->_date = NULL;
	st->_current = 0;
	st->_size = 0;
}
//检测是否扩容,并返回需要插入的指针
static void* Capacity(stack* st)
{
	if (st->_size == st->_current)//空间已满需要扩容
	{
		void* _date = realloc(st->_date, st->_size * st->_type * 2);
		if (_date == NULL)
		{
			perror("扩容失败sttor");
			exit(-1);
		}
		else
		{
			st->_date = _date;
			st->_size *= 2;
		}
	}
	char* str1 = (char*)st->_date + st->_type * st->_current;
	st->_current++;
	return str1;
}
//无类型入栈
void Stack_Push(stack* st,const void* x)// 压栈,增加元素 O(1)
{
	memcpy(Capacity(st), x, st->_type);
}
//char型入栈
void Stack_Push_char(stack* st,const char x)
{
	*(char*)Capacity(st) = x;
	//memcpy(Capacity(st), &x, st->_type);
}
//char*型入栈
void Stack_Push_Char(stack* st,const char* x)
{
	*(char**)Capacity(st) = x;
	//memcpy(Capacity(st), &x, st->_type);
}
//char[]数组字符串型入栈
void Stack_Push_charArray(stack* st, const char* x)
{
	strcpy(Capacity(st),x);
}
//int型入栈
void Stack_Push_int(stack* st, const int x)
{
	*(int*)Capacity(st) = x;
}
//int*型入栈
void Stack_Push_Int(stack* st, const int* x)
{
	*(int**)Capacity(st) = x;
	//memcpy(Capacity(st), &x, st->_type);
}
int[]数组型
//void Stack_Push_int(stack* st, const int *x)
//{
//
//}
//出一个数据
void Stack_pop(struct stack* st)//移除栈顶元素 O(1)
{
	if (st->_current > 0)
		st->_current--;
}
//无类型取元素
void* Stack_top(struct stack* st)// 取得栈顶元素(但不删除)O(1)
{
	char* _date = (char*)st->_date + st->_type * (st->_current - 1);
	return _date;
}
//char型取元素
char Stack_top_char(stack* st)
{
	return *(char*)Stack_top(st);
}
//char*型取元素
char* Stack_top_Char(stack* st)
{
	return *(char**)Stack_top(st);
}
//char[]数组字符串型取元素
char* Stack_top_charArray(stack* st)
{
	return (char*)Stack_top(st);
}
//int型取元素
int Stack_top_int(stack* st)
{
	return *(int*)Stack_top(st);
}
//int*型取元素
int* Stack_top_Int(stack* st)
{
	return *(int**)Stack_top(st);
}
//判断是否为空
bool Stack_empty(struct stack* st)//检测栈内是否为空,空为真 O(1)
{
	return !st->_current;
}
//当前最大能存储数据量
int Stack_size(struct stack* st)//返回stack内元素的个数 O(1)
{
	return st->_current;
}
//文本转数字
static size_t TurnNumber(char* arr)
{
	size_t len = strlen(arr);
	size_t  num=0;
	for (size_t i = 0; i < len; i++)
	{
		if (arr[i] >= '0' && arr[i] <= '9')
			num = num * 10 + arr[i] - '0';
	}
	return num;
}
//初始化函数
void StackINIT(stack* st,const char* arr, ...)
{
	char buf[20];
	strcpy(buf, arr);
	size_t len = strlen(buf);
	//printf("去空格前:%s\n", buf);
	//去掉字符串空格
	for (size_t i = 0; i < len; i++)
	{
		if (buf[len-1-i] == ' ')
		{
			for (size_t j = 0; j < i+1; j++)
			{
				buf[len - 1 - i+j] = buf[len - i+j];
			}
		}
	}
	//printf("去空格后:%s  长度:%d\n", buf,strlen(buf));
	if (strcmp(buf, "char")==0)
	{
		st->_type = sizeof(char);
		st->push = Stack_Push_char;//入栈
		st->top = Stack_top_char;//取得栈顶元素(但不删除)O(1)
	}
	else if (strcmp(buf, "char*")==0)
	{
		st->_type = sizeof(char*);
		st->push = Stack_Push_Char;//入栈
		st->top = Stack_top_Char;//取得栈顶元素(但不删除)O(1)
	}
	else if (strncmp(buf, "char[",5) == 0 && buf[strlen(buf) - 1])
	{
		char num[20];
		size_t n = strlen(buf) - 6;
		strncpy(num, &buf[5],n );
		num[n]='\0';
		st->_type = sizeof(char)*TurnNumber(num);
		st->push = Stack_Push_charArray;//入栈
		st->top = Stack_top_charArray;//取得栈顶元素(但不删除)O(1)
		//printf("%d\n", st->_type);
	}
	else if (strcmp(buf, "int")==0)
	{
		st->_type = sizeof(int);
		st->push = Stack_Push_int;//入栈
		st->top = Stack_top_int;//取得栈顶元素(但不删除)O(1)
	}
	else if (strcmp(buf, "int*")==0)
	{
		st->_type = sizeof(int*);
		st->push = Stack_Push_Int;//入栈
		st->top = Stack_top_Int;//取得栈顶元素(但不删除)O(1)
	}
	//else if (strncmp(buf, "int[", 4) == 0 && buf[strlen(buf) - 1])
	//{
	//	char num[20];
	//	size_t n = strlen(buf) - 5;
	//	strncpy(num, &buf[4], n);
	//	num[n] = '\0';
	//	st->_type = sizeof(int) * TurnNumber(num);
	//	st->push = Stack_Push_charArray;//入栈
	//	st->top = Stack_top_charArray;//取得栈顶元素(但不删除)O(1)
	//	printf("%d\n", st->_type);
	//}
	else
	{
		va_list args;//接收可变参数,
		va_start(args, arr);
		size_t n = va_arg(args, size_t);//依次访问参数,需指定按照什么类型读取数据  
		if (n <= 0 || n > 1000)
		{
			perror("您的类型本程序无内置请输入类型的字符数量,将以void指针形式返回,请强转后解引用使用(上限1000字节)\n");
			exit(-1);
		}
		va_end(args);//参数使用结束  
		st->_type = n;
		st->push = Stack_Push;//入栈
		st->top = Stack_top;//取得栈顶元素(但不删除)O(1)
	}
	
	st->clear = Stack_clear;//清空stack的队列,释放内存
	st->pop = Stack_pop;//出栈
	st->empty = Stack_empty;//检测栈内是否为空,空为真 O(1)
	st->size = Stack_size;//返回stack内元素的个数 O(1)
	
	st->_current = 0;
	st->_date = malloc(st->_type * MAXNUM);
	if (st->_date == NULL)
	{
		perror("初始化sttor失败");
		exit(-1);
	}
	else
	{
		st->_size = MAXNUM;
	}
}
test.c(测试代码)
#include"stack.h"
typedef struct user
{
	char name [20];
	int age;
}user;
void int_test()
{
	stack st;//创建容器
	StackINIT(&st,"int");//初始化容器
	printf("int类型数据测试\n");

	st.push(&st,10);//压栈
	st.push(&st, 123);//压栈
	st.push(&st,111);//压栈
	//st.pop(&st);
	st.push(&st, 6565);//压栈
	st.push(&st, 100);//压栈
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		printf("%d\n", st.top(&st));
		st.pop(&st);
	}
	printf("stack最大能储存%d个\n\n", st._size);
	st.clear(&st);
}
void Int_test()//int指针测试
{
	stack st;//创建容器
	StackINIT(&st, "int*");//初始化容器
	printf("int*类型数据测试\n");
	int num1 = 10;
	st.push(&st, &num1);//压栈
	int num2 = 11;
	st.push(&st, &num2);//压栈
	int num3 = 12;
	st.push(&st,&num3);//压栈
	*st.top(&st) = 1000;
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		printf("%d\n", *st.top(&st));
		st.pop(&st);
	}
	printf("stack最大能储存%d个\n\n", st._size);
	st.clear(&st);
}
//void int00_test()
//{
//	printf("int[]数组类型数据测试\n");
//	stack st;//创建容器
//	StackINIT(&st, "int[100]");//初始化容器
//}
void char_test()
{
	stack st;//创建容器
	StackINIT(&st,"char");//初始化容器
	printf("char类型数据测试\n");
	st.push(&st,'a');//压栈
	st.push(&st, 'b');//压栈
	st.push(&st, 'c');//压栈
	st.push(&st, 'd');//压栈
	st.pop(&st);
	st.push(&st, 'e');//压栈
	st.push(&st, 'f');//压栈
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		printf("%c\n", st.top(&st));
		st.pop(&st);
	}
	printf("stack最大能储存%d个\n\n", st._size);
	st.clear(&st);
}
void Char_test()//char指针测试
{
	stack st;//创建容器
	StackINIT(&st, "char*");//初始化容器
	printf("char*类型数据测试\n");
	char arr1 = 'a';
	st.push(&st, &arr1);//压栈
	char arr2 = 'b';
	st.push(&st, &arr2);//压栈
	char arr3 = 'c';
	st.push(&st, &arr3);//压栈
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		printf("%c\n", *st.top(&st));
		st.pop(&st);
	}
	printf("stack最大能储存%d个\n\n", st._size);
	st.clear(&st);
}
void char00_test()
{
	printf("char[]数组类型数据测试\n");
	stack st;//创建容器
	StackINIT(&st, "char[100]");//初始化容器
	st.push(&st, "玛卡巴卡");//压栈
	st.push(&st, "私房菜");//压栈
	st.push(&st, "鸭大帅");//压栈
	strcpy(st.top(&st), "1231");
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		printf("%s\n",st.top(&st));
		st.pop(&st);
	}
	printf("stack最大能储存%d个\n\n", st._size);
	st.clear(&st);
}
void uesr_test()
{
	stack st;//创建容器
	StackINIT(&st,"user", sizeof(user));//初始化容器
	printf("自定义结构体类型数据测试\n");
	user us;//创建要压栈的数据变量

	strcpy(us.name,"玛卡巴卡");
	us.age = 17;
	st.push(&st, &us);//压栈
	//printf("名字%s,年龄%d\n", (*((user*)st.top(&st))).name, us.age);

	strcpy(us.name, "辉小崔");
	us.age = 18;
	st.push(&st, &us);//压栈
	//printf("%c\n", *(int*)st.top(&st));

	//st.pop(&st);//出栈

	strcpy(us.name, "莫");
	us.age = 19;
	st.push(&st, &us);//压栈

	strcpy(us.name, "唔西迪西");
	us.age = 18;
	st.push(&st, &us);//压栈

	strcpy(us.name, "裂开石榴");
	us.age = 20;
	st.push(&st, &us);//压栈
	
	printf("元素个数%d\n",st.size(&st));

	printf("下面为大佬遍历,年龄瞎写\n");
	while (!st.empty(&st))
	{
		us = *(user*)st.top(&st);
		printf("%s大佬,年龄%d\n", us.name,us.age);
		st.pop(&st);
	}
	printf("stack空间大小为%d\n\n", st._size);
	st.clear(&st);
}

int main()
{
	//int00_test();
	char00_test();
	int_test();
	Int_test();
	char_test();
	Char_test();
	uesr_test();
}
测试结果

 

 

 

 

 

 

 

 

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/874751.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存