链式栈的实现

链式栈的实现

栈相比于链表,它是一种特殊的数据模型,两者既有联系(通过链表的api函数可以改造出栈的api函数,这其中的原因在于两者的底层逻辑是有相似的地方的,即:通过在链表的头部操作元素,就可以模拟出栈),区别在于,链表和栈之间的对变量生命周期的管理不一样;
在实现栈的过程中,我们不可避免的用到了链表的api函数;

//头文件1:栈的头文件,定义了数据类型和栈的api函数
#define _MY_LINKSTACK_H
typedef void LinkStack;//把栈节点适配成链表节点,添加进链表库
LinkStack* LinkStack_Create();
void LinkStack_Destroy(LinkStack* stack);
void LinkStack_Clear(LinkStack* stack);
int LinkStack_Push(LinkStack* stack, void* item);
void* LinkStack_Pop(LinkStack* stack);
void* LinkStack_Top(LinkStack* stack);
int LinkStack_Size(LinkStack* stack);
//int LinkStack_Capacity(LinkStack* stack);
#endif
//头文件2:单向链表的头文件,里面主要声明了链表的api函数,在模拟栈的过程中,我们用到了链表的api
#ifndef _MYLINKLIST_H_
#define _MYLINKLIST_H_

typedef void LinkList;
typedef struct _tag_LinkListNode
{
	struct _tag_LinkListNode* next;
}LinkListNode;
LinkList* LinkList_Create();
void LinkList_Destroy(LinkList* list);
void LinkList_Clear(LinkList* list);
int LinkList_Length(LinkList* list);
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);
LinkListNode* LinkList_Get(LinkList* list, int pos);
LinkListNode* LinkList_Delete(LinkList* list, int pos);
#endif

//c文件1:链表的api函数的实现
#include<iostream>
#include"LinkList.h"
using namespace std;
typedef struct _tag_LinkList
{
	LinkListNode header;
	int length;
}TLinkList;
LinkList* LinkList_Create()
{
	TLinkList* tmp = NULL;
	tmp = (TLinkList*)malloc(sizeof(TLinkList));
	if (tmp == NULL)
	{
		cout << "LinkList_Create() error" << endl;
		return NULL;
	} 
	memset(tmp, 0, sizeof(TLinkList)); 
	return tmp;
}
void LinkList_Destroy(LinkList* list)
{
	if (list == NULL)
	{
		return;
	}
	free(list);
	return;
}
void LinkList_Clear(LinkList* list)
{
	TLinkList* tlist = NULL;
	tlist = (TLinkList*)list;
	if (tlist == NULL)
	{
		return;
	}
	tlist->header.next = NULL;
	tlist->length = 0;
	return;
}
int LinkList_Length(LinkList* list)
{
	TLinkList* tlist = NULL;
	tlist = (TLinkList*)list;
	if (tlist == NULL)
	{
		return -1;
	}
	return tlist->length;
}
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
	int i = 0;
	LinkListNode *pcur=NULL;
	TLinkList* tList = NULL;
	tList = (TLinkList*)list;
	pcur = &(tList->header);
	if (list == NULL || node == NULL || pos < 0)
	{
		return -1;
	}
	for (i = 0; i < pos; i++)
	{
		pcur = pcur->next;
	}
	node->next = pcur->next;
	pcur->next = node;
	tList->length++;
	return 0;
}
LinkListNode* LinkList_Get(LinkList* list, int pos)
{
	int i = 0;
	LinkListNode* pcur = NULL;
	TLinkList* tList = NULL;
	tList = (TLinkList*)list;
	pcur = &(tList->header);
	if (list == NULL ||  pos < 0)
	{
		return NULL;
	}
	for (i = 0; i < pos; i++)
	{
		pcur = pcur->next;
	}
	return pcur->next;
}
LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
	int i = 0;
	LinkListNode* pcur = NULL;
	LinkListNode* ret = NULL;
	TLinkList* tlist=NULL;
	tlist = (TLinkList*)list;
	pcur = &(tlist->header);
	if (list == NULL || pos < 0)
	{
		return NULL;
	}
	for (i = 0; i < pos; i++)
	{
		pcur = pcur->next;
	}
	ret=pcur->next;
	pcur->next = ret->next;
	tlist->length--;
	//free(ret);
	return ret;
}

//c文件2:栈的api函数的实现
#include<iostream>
using namespace std;
#include"LinkStack.h"
#include"LinkList.h"

//压栈相当于不断从栈的头部插入元素,压栈需要做一个结构体,将栈节点适配成链表节点插入到链表库中
typedef struct _tag_LinkStack
{
	LinkListNode* node;//链表节点
	void* item;//将栈节点放进结构体中,串联起来
}TLinkStack;

LinkStack* LinkStack_Create()
{
	return LinkList_Create();
}

//栈的销毁和清空涉及栈的生命周期
void LinkStack_Destroy(LinkStack* stack)
{
	LinkStack_Clear(stack);//释放栈中的节点
	LinkList_Destroy(stack);//释放句柄(头节点的指针);
	return;
}
void LinkStack_Clear(LinkStack* stack)
{
	while (LinkList_Length(stack) > 0)
	{
		LinkStack_Pop(stack);
	}
	return;
}

int LinkStack_Push(LinkStack* stack, void* item)
{
	int ret = 0;
	TLinkStack* tmp = NULL;
	tmp =(TLinkStack*) malloc(sizeof(TLinkStack));
	tmp->item = item;
	ret=LinkList_Insert(stack, (LinkListNode*)tmp, 0);
	if (ret != 0)
	{
		cout << "function LinkStack_push error" << ret << endl;
		return -1;
		free(tmp);//注意细节,为了避免内存泄露,释放内存;
	}
	return ret;
}
//相当于不断从链表的头部删除元素;
void* LinkStack_Pop(LinkStack* stack)
{
	TLinkStack* tmp = NULL;
	void* item = NULL;
	tmp = (TLinkStack*)LinkList_Delete(stack, 0);
	if (tmp == NULL)
	{
		return NULL;
	}
	item = tmp->item;
	free(tmp);//插入的时候手动在堆区分配了内存,将元素删除之后需要将内存释放,防止内存泄露
	return item;//将链表节点转换成栈节点返回;
}
//获取0号位置的元素;
void* LinkStack_Top(LinkStack* stack)
{
	TLinkStack* tmp=NULL;
	tmp =(TLinkStack*)LinkList_Get(stack, 0);
	if (tmp == NULL)
	{
		return NULL;
	}

	return tmp->item;
}
int LinkStack_Size(LinkStack* stack)
{
	return LinkList_Length(stack);
}

//c文件3:栈的上层应用函数的,即栈的测试框架
#include<iostream>
using namespace std;
#include"LinkStack.h"
int main()
{
	LinkStack* stack = NULL;
	stack = LinkStack_Create();
	int a[5], i = 0;
	for (i = 0; i < 5; i++)
	{
		a[i] = i + 1;
		LinkStack_Push(stack, &a[i]);//向栈中添加元素;
	}

	//获取栈的属性
	cout << "len: " << LinkStack_Size(stack) << endl;
	cout << "top: " << *(int*)LinkStack_Top(stack) << endl;

	//元素出栈
	/*while (LinkStack_Size(stack) > 0)
	{
		int tmp = 0;
		tmp = *(int*)LinkStack_Pop(stack);
		cout << tmp << " ";

	}这里屏蔽的原因是,在测试LinkStack_Destroy这个函数的时候,需要栈中有元素*/
	cout << "*****" << endl;
	LinkStack_Destroy(stack);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值