链式栈接口设计(C语言)

链式栈接口设计

/**

* @file name: 链式栈接口设计

* @brief

* @author ni456xinmie@163.com

* @date 2024/04/24

* @version 1.0 :版本

* @property :类比于顺序栈,链式栈也有一个栈顶和栈底。根据链式表特性,将第一个插入的值作为栈底,即尾节点作为栈底。首节点作为栈顶。

* @note

* CopyRight (c) 2023-2024 ni456xinmie@163.com All Right Reseverd

*/


功能函数:构造链式结点

typedef int DataType_t;	 // 指的是链式栈中的结点有效数据类型
typedef struct LinkStack // 构造结点,链表中所有结点的数据类型应该是相同的
{
	DataType_t data;		// 结点的数据域
	struct LinkStack *next; // 结点的指针域
} LStack_t;
LStack_t *LStack_Create(void) // 创建一个空链表,空链表应该有一个头结点,对链表进行初始化
{
	// 1.创建一个头结点即栈顶并对头结点申请内存
	LStack_t *Top = (LStack_t *)calloc(1, sizeof(LStack_t));
	if (NULL == Top)
	{
		perror("Calloc memory for Top is Failed");
		exit(-1);
	}
	// 2.对头结点进行初始化,不存储有效内容,因此数据域初始化为0
	Top->next = NULL;
	Top->data = 0;
	// 3.把头结点的地址返回即可
	return Top;
}

创建新的结点,并对新结点进行初始化(数据域 + 指针域)

LStack_t *LStack_NewNode(DataType_t data)
{
	// 1.创建一个新结点并对新结点申请内存
	LStack_t *New = (LStack_t *)calloc(1, sizeof(LStack_t));
	if (NULL == New)
	{
		perror("Calloc memory for NewNode is Failed");
		return NULL;
	}
	// 2.对新结点的数据域和指针域进行初始化
	New->data = data;
	New->next = NULL;
	return New;
}

功能函数:入栈。因为是链式栈,因此只能允许在头部进行入栈及出栈

bool LStack_Push(LStack_t *Top, DataType_t data)
{
	// 1.创建新的结点,并对新结点进行初始化
	LStack_t *New = LStack_NewNode(data);
	if (NULL == New)
	{
		printf("can not insert new node\n");
		return false;
	}
	/* 此处考虑两种情况,如果链表为空或者非空:
	1.如果为空,即满足Top->next==NULL;
	2.如果为非空,Top->next!=NULL,用下述代码也能满足;
	综上,可以不用if语句判断是否为空链表。
	*/
	New->next = Top->next;
	Top->next = New;
	return true;
}

功能函数:出栈

bool LStack_Pop(LStack_t *Top)
{
	// 对首节点的地址进行备份
	LStack_t *PTop = Top->next;
	if (NULL == PTop) // 判断是否为空表 judge is this a empty list.
	{
		printf("This is a empty list.\n");
		return false;
	}
	/* 此处考虑两种情况,如果链表仅有一个元素或一个以上的元素:
	1.如果仅有一个元素,即满足PTop->next==NULL;
	2.如果为非空,PTop->next!=NULL,用下述代码也能满足;
	综上,可以不用if语句判断是否为仅有一个元素。
	*/
	Top->next = PTop->next;
	PTop->next = NULL;
	free(PTop);
	return true;
}

功能函数:链表整体释放

bool LStack_Free(LStack_t *Top) // 实现链式栈的整体释放
{
	// 对首节点的地址进行备份
	if (Top == NULL)
	{
		printf("The list doesn't exist.\n");
		return false;
	}
	LStack_t *PTop;
	while (Top)
	{
		PTop = Top;
		Top = Top->next;
		free(PTop);
	}
	return true;
}

功能函数:链式栈元素展示

void LStack_Print(LStack_t *Top)
{
	LStack_t *PTop = Top; // 对链表的头文件的地址进行备份
	if (Top == NULL)
	{
		printf("The list doesn't exist.\n");
		return;
	}
	printf("4\n");
	while (PTop->next) // 判断是否为空链表
	{
		// 把头的直接后继作为新的头结点
		PTop = PTop->next;

		// 输出头结点的直接后继的数据域
		printf("data = %d  ", PTop->data);
	}
}

主函数:进行功能函数测试

int main(int argc, char const *argv[])
{
	LStack_t *H = (LStack_t *)calloc(1, sizeof(LStack_t));
	LStack_Push(H, 10);
	LStack_Push(H, 20);
	LStack_Push(H, 30);
	LStack_Print(H);
	printf("1\n"); // 测试插入功能函数
	LStack_Pop(H);
	LStack_Print(H);
	printf("2\n"); // 测试删除功能函数
	LStack_Free(H);
	return 0;
}

posted @ 2024-04-25 00:01  Rice_rice  阅读(13)  评论(0编辑  收藏  举报