链式链表实现栈模型(C)

栈满足先进后出的功能,用于在很多场景,可以发挥意想不到的功能。

栈是一种特殊的线性表,因此可以通过线性链表来实现栈的功能。线性链表有顺序,和链式两种,这里选取链式链表实现栈(顺序请参考上一博客)。在链式链表实现栈模型,栈顶可以可以在链表的头部或尾部,用链表的尾部作为栈顶,入栈和出栈要遍历链表节点直到遍历到链表的尾部,过程复杂效率低下。但用链表的头部作为栈顶,入栈和出栈只用操作链表的首元素,不涉及到遍历链表,效率较高。因此,这里我们采用链表的头部做为栈顶。

详细讲解参照https://www.bilibili.com/video/av27904891/?p=1

本次使用工具为vs2017,作者水平有限,若有问题请指出。

栈头文件:Stack_Link_C.h

#pragma once

typedef void StackData;
typedef void Stack;

//定义栈节点数据类型
typedef struct StackNode
{
	struct StackNode *Next;
	StackData *data;

}StackNode;

//定义链表头
typedef struct StackHead
{
	StackNode Head;
	int StackLen;
}StackHead;

//创建栈
Stack *CreateStack();

//销毁栈
int DestoryStack(Stack **_stack);

//清除栈
int ClearStack(Stack *_stack);

//获取栈的元素个数
int GetStackLen(Stack *_stack);

//元素压入栈
int PushStack(Stack *_stack, StackData *_data);

//弹出元素
StackData *PopStack(Stack *_stack);

//获取栈顶元素
StackData *GetTopData(Stack *_stack);

栈源文件:Stack_Link_C.cpp

# include"pch.h"
# include"stdio.h"
# include"stdlib.h"
# include"Stack_Link_C.h"


//创建栈,返回栈的地址
Stack *CreateStack()
{
	int ret = 0;
	StackHead *stack = (StackHead *)malloc(sizeof(StackHead));
	if (stack == NULL)
	{
		printf("Malloc Stack Head Error :CreateStack() \n");
	}
	stack->Head.Next = NULL;
	stack->Head.data = NULL;
	stack->StackLen = 0;

	return (Stack *)stack;
}

//销毁栈
int DestoryStack(Stack **_stack) 
{
	int ret = 0;
	if (_stack == NULL)
	{
		printf("Parameters is null :DestoryStack() \n");
		ret = -1;
		return ret;
	}
	//数据类型转换
	StackHead **stack = (StackHead **)_stack;
	StackNode *current = (*stack)->Head.Next;       //current指向0号节点
	StackNode *temp = (*stack)->Head.Next->Next;    //temp指向1号节点
	for (int i=0; i<(*stack)->StackLen-1; i++)
	{
		if (current != NULL)
		{
			free(current);
			current = temp;
			temp = current->Next;
		}
	}
	(*stack)->Head.data = NULL;
	(*stack)->Head.Next = NULL;
	(*stack)->StackLen = 0;
	*stack = NULL;
	return ret;
}
//清除栈
int ClearStack(Stack *_stack) 
{
	int ret = 0;
	if (_stack == NULL)
	{
		printf("Parameters is null :ClearStack() \n");
		ret = -1;
		return ret;
	}
	//数据类型转换
	StackHead *stack = (StackHead *)_stack;
	StackNode *current = (stack)->Head.Next;       //current指向0号节点
	StackNode *temp = (stack)->Head.Next->Next;    //temp指向1号节点
	for (int i = 0; i < (stack)->StackLen-1; i++)
	{
		if (current != NULL)
		{
			free(current);
			current = temp;
			temp = current->Next;
		}
	}
	(stack)->Head.data = NULL;
	(stack)->Head.Next = NULL;
	(stack)->StackLen = 0;
	return ret;
}
//获取栈的元素个数
int GetStackLen(Stack *_stack)
{
	int ret = 0;
	if (_stack == NULL)
	{
		printf("Parameters is null :GetStackLen() \n");
		ret = -1;
		return ret;
	}
	//数据类型转换
	StackHead *stack = (StackHead *)_stack;
	return stack->StackLen;
}
//元素压入栈
int PushStack(Stack *_stack, StackData *_data) 
{
	int ret = 0;
	if (_stack == NULL || _data == NULL)
	{
		printf("Parameters is null :PushStack() \n");
		ret = -1;
		return ret;
	}
	
	//数据类型转换
	StackHead *stack = (StackHead *)_stack;
	StackData *data = (StackData *)_data;
	StackNode *datacopy = (StackNode *)malloc(sizeof(StackNode));  //分配内存,把数据拷贝进来
	if (datacopy == NULL)
	{
		printf("Malloc StackNode Error :PushStack() \n");
		ret = -1;
		return ret;
	}
	//拷贝数据
	datacopy->data = data;
	datacopy->Next = NULL;
	if (stack->StackLen == 0)  //空栈,第一次插入数据
	{
		stack->Head.Next = datacopy;
		datacopy->Next = NULL;
		stack->StackLen++;
	}
	else
	{
		datacopy->Next = stack->Head.Next;
		stack->Head.Next = datacopy;
		stack->StackLen++;
	}
	return ret;
}
//弹出元素
StackData *PopStack(Stack *_stack)
{
	if (_stack == NULL)
	{
		printf("Parameters Error :PopStack() \n");
		return NULL;
	}
	//数据类型转换
	StackHead *stack = (StackHead *)_stack;
	StackNode *data = NULL;
	if (stack->StackLen <= 0)
	{
		printf("Stack hasn't element :PopStack() \n");
		return NULL;
	}
	else if(stack->StackLen == 1) //只有一个元素
	{
		data = (StackNode *)stack->Head.Next->data;
		stack->Head.Next = NULL;    //头指针为NULL
		stack->StackLen--;
	}
	else
	{
		data = (StackNode *)stack->Head.Next->data;
		stack->Head.Next = stack->Head.Next->Next;  //头指针指向1号节点
		stack->StackLen--;
	}
	return data;
}
//获取栈顶元素
StackData *GetTopData(Stack *_stack)
{
	if (_stack == NULL)
	{
		printf("Parameters Error :GetTopData() \n");
		return NULL;
	}
	//数据类型转换
	StackHead *stack = (StackHead *)_stack;
	if (stack->StackLen <= 0)
	{
		printf("Stack hasn't element :GetTopData() \n");
		return NULL;
	}
	return (StackData *)stack->Head.Next->data;
}

栈的测试源文件:Stack_Link_C_Test.cpp

# include"pch.h"
# include"stdio.h"
# include"stdlib.h"
# include"Stack_Link_C.h"
typedef struct stu
{
	int age;
}stu;


//测试int型数据
void test1()
{
	int a[] = { 1,2,3,4,5,6,7,8 };
	int ret = 0;
	int *data = NULL;
	Stack *stack = CreateStack();


	//压入元素
	ret = PushStack(stack,(StackData *)a);
	ret = PushStack(stack, (StackData *)(a + 1));
	ret = PushStack(stack, (StackData *)(a + 2));
	ret = PushStack(stack, (StackData *)(a + 3));
	ret = PushStack(stack, (StackData *)(a + 4));
	ret = PushStack(stack, (StackData *)(a + 5));

	//弹出元素
	printf("测试元素入栈和出栈 \n");

	data = (int *)PopStack(stack);
	printf("%d  ",*data);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);

	//获取栈顶元素
	data = (int *)GetTopData(stack);
	printf("%d  ", *data);

	//测试清空栈
	printf("\n 测试清空栈再进栈出栈 \n");

	ret = ClearStack(stack);
	ret = PushStack(stack, (StackData *)(a + 6));
	ret = PushStack(stack, (StackData *)(a + 6));
	ret = PushStack(stack, (StackData *)(a + 7));
	ret = PushStack(stack, (StackData *)a);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);
	data = (int *)PopStack(stack);
	printf("%d  ", *data);

	data = (int *)PopStack(stack);
	if (data != NULL)
	{
		printf("%d  ", *data);
	}

	//测试销毁栈
	printf("\n 测试销毁栈 \n");
	ret = PushStack(stack, (StackData *)(a + 7));
	ret = PushStack(stack, (StackData *)a);
	ret = PushStack(stack, (StackData *)(a + 7));
	ret = PushStack(stack, (StackData *)a);
	ret = DestoryStack(&stack);

	ret = PushStack(stack, (StackData *)a);
}

//测试stu结构体
void test2()
{
	stu a0,a1,a2,a3,a4,a5,a6,a7,a8,a9;
	a0.age = 50;
	a1.age = 51;
	a2.age = 52;
	a3.age = 53;
	a4.age = 54;
	a5.age = 55;
	a6.age = 56;
	a7.age = 57;
	a8.age = 58;
	a9.age = 59;

	int ret = 0;
	stu *data = NULL;
	Stack *stack = CreateStack();


	//压入元素
	ret = PushStack(stack, (StackData *)(&a0));
	ret = PushStack(stack, (StackData *)(&a1));
	ret = PushStack(stack, (StackData *)(&a2));
	ret = PushStack(stack, (StackData *)(&a3));
	ret = PushStack(stack, (StackData *)(&a4));
	ret = PushStack(stack, (StackData *)(&a5));

	//弹出元素
	printf("测试元素入栈和出栈 \n");

	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);

	//获取栈顶元素
	data = (stu *)GetTopData(stack);
	printf("%d  ", data->age);

	//测试清空栈
	printf("\n 测试清空栈再进栈出栈 \n");

	ret = ClearStack(stack);
	ret = PushStack(stack, (StackData *)(&a6));
	ret = PushStack(stack, (StackData *)(&a6));
	ret = PushStack(stack, (StackData *)(&a7));
	ret = PushStack(stack, (StackData *)&a0);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);
	data = (stu *)PopStack(stack);
	printf("%d  ", data->age);

	data = (stu *)PopStack(stack);
	if (data != NULL)
	{
		printf("%d  ", data->age);
	}

	//测试销毁栈
	printf("\n 测试销毁栈 \n");
	ret = PushStack(stack, (StackData *)(&a7));
	ret = PushStack(stack, (StackData *)&a0);
	ret = PushStack(stack, (StackData *)(&a7));
	ret = PushStack(stack, (StackData *)&a0);
	ret = DestoryStack(&stack);

	ret = PushStack(stack, (StackData *)&a0);
}
int main()
{
	test1();
	test2();
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值