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

 已经重新整理,并且拆分成多文件,阅读更方便

跳转链接

面向对象方式重写源码

众所周知stack是C++中的,但c没有所以就写了这个,尽量将名字都写成一样的,好方便后期使用

因为c没有模板这个概念,所以此代码为了实现所有数据类型,本身是无类型的,采用内存拷贝实现。

内置函数获取的数据都是以void指针的形式返回,需要强转成自己使用的类型

Plus版,用int,char,int*,char*,char[]数组(字符串类型)时,不用在需要强转指针后在解引用使用了。传送门

目录

内置函数

插入函数

void Stack_Push(stack* vec, void* x);// 压栈,增加元素 O(1)

删除函数

void Stack_pop(struct stack* vec);//移除栈顶元素 O(1)

void Stack_clear(struct stack* vec);//清空stack(栈),释放内存

遍历函数

void* Stack_top(struct stack* vec);// 取得栈顶元素(但不删除)O(1)

判断函数

bool Stack_empty(struct stack* vec);//检测栈内是否为空,空为真 O(1)

大小函数

int Stack_size(struct stack* vec);//返回stack内元素的个数 O(1)

初始化函数

void VectorINIT(stack* vec, int n);//stack容器初始化函数

测试结果

完整代码

stack.h(函数声明)

stack.c(函数实现)

test.c(测试代码)


内置函数

插入函数

void Stack_Push(stack* vec, void* x);// 压栈,增加元素 O(1)

void Stack_Push(stack* vec,void* x)// 压栈,增加元素 O(1)
{
	if (vec->_size ==vec->_current)//空间已满需要扩容
	{
		void* _date = realloc(vec->_date, vec->_size * vec->_type * 2);
		if (_date == NULL)
		{
			perror("扩容失败vector");
			exit(-1);
		}
		else
		{
			vec->_date = _date;
			vec->_size *= 2;
		}
	}
	char* str1 = (char*)vec->_date + vec->_type * vec->_current;
	memcpy(str1,x, vec->_type);
	vec->_current++;
}

删除函数

void Stack_pop(struct stack* vec);//移除栈顶元素 O(1)

void Stack_pop(struct stack* vec)//移除栈顶元素 O(1)
{
	if(vec->_current>0)
	vec->_current--;
}

void Stack_clear(struct stack* vec);//清空stack(栈),释放内存

void Stack_clear(stack* vec)
{
	free(vec->_date);
	vec->_date = NULL;
	vec->_current = 0;
	vec->_size = 0;
}

遍历函数

void* Stack_top(struct stack* vec);// 取得栈顶元素(但不删除)O(1)

void* Stack_top(struct stack* vec)// 取得栈顶元素(但不删除)O(1)
{
	char* _date = (char*)vec->_date + vec->_type * (vec->_current-1);
	return _date;
}

判断函数

bool Stack_empty(struct stack* vec);//检测栈内是否为空,空为真 O(1)

bool Stack_empty(struct stack* vec)//检测栈内是否为空,空为真 O(1)
{
	return !vec->_current;
}

大小函数

int Stack_size(struct stack* vec);//返回stack内元素的个数 O(1)

int Stack_size(struct stack* vec)//返回stack内元素的个数 O(1)
{
	return vec->_current;
}

初始化函数

void VectorINIT(stack* vec, int n);//stack容器初始化函数

void VectorINIT( stack* vec,int n)
{
	vec->clear = Stack_clear;//清空stack的队列,释放内存
	vec->push = Stack_Push;//入栈
	vec->pop = Stack_pop;//出栈
	vec->top = Stack_top;//取得栈顶元素(但不删除)O(1)
	vec->empty = Stack_empty;//检测栈内是否为空,空为真 O(1)
	vec->size = Stack_size;//返回stack内元素的个数 O(1)
	vec->_type = n;
	vec->_current = 0;
	vec->_date = malloc(vec->_type * VECTORNUM);
	if (vec->_date == NULL)
	{
		perror("初始化vector失败");
		exit(-1);
	}
	else
	{
		vec->_size = VECTORNUM;
	}
}

测试结果

完整代码

stack.h(函数声明)

#pragma once
#define _CRT_SECURE_NO_DEPRECATE  1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define VECTORNUM 4//初始数组大小
typedef struct stack
{
	void* _date;//指向自定义数组类型
	int  _current;//当前元素个数
	int _size;//元素最大个数
	int _type;//类型占用字节数
	//void (*INIT) (stakc* vec, int n);//初始化
	void(*push)(struct stack* vec, void*);//压栈,增加元素 O(1)
	void (*pop)(struct stack* vec);//移除栈顶元素 O(1)
	void* (*top)(struct stack*);// 取得栈顶元素(但不删除)O(1)
	bool (*empty)(struct stack*);// 检测栈内是否为空,空为真 O(1)
	int (*size)(struct stack*);//返回stack内元素的个数 O(1)
}stack;
void Stack_Push(stack* vec, void* x);// 压栈,增加元素 O(1)
void Stack_pop(struct stack* vec);//移除栈顶元素 O(1)
void* Stack_top(struct stack* vec);// 取得栈顶元素(但不删除)O(1)
bool Stack_empty(struct stack* vec);//检测栈内是否为空,空为真 O(1)
int Stack_size(struct stack* vec);//返回stack内元素的个数 O(1)
//stack容器初始化函数
void VectorINIT(stack* vec, int n);

stack.c(函数实现)

#include"stack.h"
void Stack_Push(stack* vec,void* x)// 压栈,增加元素 O(1)
{
	if (vec->_size ==vec->_current)//空间已满需要扩容
	{
		void* _date = realloc(vec->_date, vec->_size * vec->_type * 2);
		if (_date == NULL)
		{
			perror("扩容失败vector");
			exit(-1);
		}
		else
		{
			vec->_date = _date;
			vec->_size *= 2;
		}
	}
	char* str1 = (char*)vec->_date + vec->_type * vec->_current;
	memcpy(str1,x, vec->_type);
	vec->_current++;
}
void Stack_pop(struct stack* vec)//移除栈顶元素 O(1)
{
	if(vec->_current>0)
	vec->_current--;
}
void* Stack_top(struct stack* vec)// 取得栈顶元素(但不删除)O(1)
{
	char* _date = (char*)vec->_date + vec->_type * (vec->_current-1);
	return _date;
}
bool Stack_empty(struct stack* vec)//检测栈内是否为空,空为真 O(1)
{
	return !vec->_current;
}
int Stack_size(struct stack* vec)//返回stack内元素的个数 O(1)
{
	return vec->_current;
}
//初始化函数
void VectorINIT( stack* vec,int n)
{
	vec->push = Stack_Push;//入栈
	vec->pop = Stack_pop;//出栈
	vec->top = Stack_top;//取得栈顶元素(但不删除)O(1)
	vec->empty = Stack_empty;//检测栈内是否为空,空为真 O(1)
	vec->size = Stack_size;//返回stack内元素的个数 O(1)
	vec->_type = n;
	vec->_current = 0;
	vec->_date = malloc(vec->_type * VECTORNUM);
	if (vec->_date == NULL)
	{
		perror("初始化vector失败");
		exit(-1);
	}
	else
	{
		vec->_size = VECTORNUM;
	}
}

test.c(测试代码)

#include"stack.h"
typedef struct user
{
	char name [20];
	int age;
}user;
void int_test()
{
	stack st;//创建容器
	VectorINIT(&st, sizeof(int));//初始化容器
	printf("int类型数据测试\n");
	int num;

	num = 10;
	st.push(&st, &num);//压栈
	printf("%d\n", *(int*)st.top(&st));

	num = 21;
	st.push(&st, &num);//压栈
	printf("%d\n", *(int*)st.top(&st));

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

	num = 123;
	st.push(&st, &num);//压栈
	num = 245;
	st.push(&st, &num);//压栈
	num = 16;
	st.push(&st, &num);//压栈
	num = 55;
	st.push(&st, &num);//压栈
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		num = *(int*)st.top(&st);
		printf("%d\n", num);
		st.pop(&st);
	}
	printf("stack空间大小为%d\n\n", st._size);
}
void char_test()
{
	stack st;//创建容器
	VectorINIT(&st, sizeof(char));//初始化容器
	printf("char类型数据测试\n");
	char c;

	c = 'a';
	st.push(&st, &c);//压栈
	printf("%c\n", *(int*)st.top(&st));

	c = 'b';
	st.push(&st, &c);//压栈
	printf("%c\n", *(int*)st.top(&st));

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

	c = 'c';
	st.push(&st, &c);//压栈
	c = 'd';
	st.push(&st, &c);//压栈
	c = 'E';
	st.push(&st, &c);//压栈
	c = 'F';
	st.push(&st, &c);//压栈
	printf("下面为元素遍历\n");
	while (!st.empty(&st))
	{
		c = *(char*)st.top(&st);
		printf("%c\n", c);
		st.pop(&st);
	}
	printf("stack空间大小为%d\n\n", st._size);
}

void uesr_test()
{
	stack st;//创建容器
	VectorINIT(&st, 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);
}

int main()
{
	int_test();
	char_test();
	uesr_test();
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值