(六)栈的链式存储设计与实现

栈的链式存储设计与实现

1、栈的链式存储是通过线性表的链式存储来模拟的。在头部添加或删除元素不会涉及到数组元素的大量移动。

2、栈的链式存储思路基本与线性表的链式存储一致,可参考线性表的链式存储。线性表的链式存储

3、相关代码

(1)linkstack.h

#ifndef _MY_LINKSTACK_H_
#define _MY_LINKSTACK_H_

typedef void LinkStack;

LinkStack* LinkStack_Create();

void LinkStack_Destory(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);

#endif

(2)linkstack.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "linkstack.h"
#include "linklist.h"

typedef struct _tag_LinkStackNode //链表业务结点
{
	LinkListNode node;//第一个域(第一个元素)
	void* item;//栈的业务结点
}TLinkStackNode;

//创建栈 相当于创建一个线性表
LinkStack* LinkStack_Create()
{
	return LinkList_Create();
}

//销毁栈相当于销毁一个线性表
//销毁栈的时候会涉及到栈元素生命周期的管理
//因为所有入栈的结点都是malloc出来的,若要清空栈,把栈中的元素弹出,也要释放结点内存
void LinkStack_Destory(LinkStack* stack)
{
	LinkStack_Clear(stack);
	LinkList_Destory(stack);
}

//清空栈相当于清空一个线性表
//清空栈的时候会涉及到栈元素生命周期的管理
void LinkStack_Clear(LinkStack* stack)
{
	if (stack == NULL)
	{
		return;
	}
	while (LinkStack_Size(stack) > 0)
	{
		LinkStack_Pop(stack);//在这个函数中已经释放结点内存
	}
	return;
}

//向栈中压入元素 相当于向线性表的头部插入元素
//void* item栈的业务结点 转化成 链表的业务结点
int LinkStack_Push(LinkStack* stack, void* item)
{
	TLinkStackNode *tmp = NULL;
	int ret = 0;
	tmp = (TLinkStackNode *)malloc(sizeof(TLinkStackNode));
	if (tmp == NULL)
	{
		return -1;
	}
	memset(tmp, 0, sizeof(TLinkStackNode));
	tmp->item = item;

	//int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);
	ret = LinkList_Insert(stack, (LinkListNode*)tmp, 0);
	if (ret != 0)
	{
		printf("func LinkList_Insert() err:%d\n", ret);
		if (tmp != NULL)
		{ 
			free(tmp);
		}
		return ret;
	}

	return ret;
}

//从栈中弹出元素 相当于从线性表的头部删除元素
//把线性表的业务结点 转化成 栈的业务结点
void* LinkStack_Pop(LinkStack* stack)
{
	void *item = NULL;//栈的业务结点
	TLinkStackNode* tmp = NULL;//线性表链式存储的业务结点
	tmp = (TLinkStackNode*)LinkList_Delete(stack, 0);
	if (tmp == NULL)
	{
		return NULL;
	}
	item = tmp->item;
	//因为LinkList_Insert()的时候分配了内存,所以LinkList_Delete()释放内存
	free(tmp);

	return item;
}

//获取栈顶元素 相当于获取线性表的0号位置元素
void* LinkStack_Top(LinkStack* stack)
{
	TLinkStackNode* tmp = NULL;
	tmp = (TLinkStackNode*)LinkList_Get(stack, 0);
	if (tmp == NULL)
	{
		return NULL;
	}
	return tmp->item;
}

//求栈的大小 相当于求线性表的length
int LinkStack_Size(LinkStack* stack)
{
	return LinkList_Length(stack);
}

(3)具体实现

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "linkstack.h"
#include "linklist.h"




void maindm007()
{
	int a[10];
	//创建栈
	LinkStack* lstack = NULL;
	lstack = LinkStack_Create();
	if (lstack == NULL)
	{
		return;
	}

	//压入元素
	for (int i = 0; i < 5; i++)
	{
		a[i] = i + 1;
		LinkStack_Push(lstack, &a[i]);
	}

	//打印栈顶元素
	printf("The LinkStack's Top:%d \n", *((int*)LinkStack_Top(lstack)));
	//打印栈的实际长度
	printf("The LinkStack's Size:%d \n", LinkStack_Size(lstack));

	//删除栈元素
	while (LinkStack_Size(lstack) > 0)
	{
		int tmp = *((int *)LinkStack_Pop(lstack));
		printf("tmp:%d ", tmp);
	}
	printf("\n");

	//销毁栈
	LinkStack_Destory(lstack);
	/*
	LinkStack* LinkStack_Create(int capacity);
	void LinkStack_Destory(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);
	*/
	system("pause");
	return;
}

猜你喜欢

转载自blog.csdn.net/ailunlee/article/details/79923383