C语言: 链式正向栈与链式反向栈

堆栈(stack): 后进先出(Last_In First_Out , LIFO)的数据模型。

下面两个都是基于链表实现的栈数据模型

链式正向栈 Dome

/************************************************************
FileName		: linkstack.h
Author			: wang 
Version			: v1.0
Date			: 2020/1/3
Description		: 【模块描述】 链式正向栈头文件
Version			: 【版本信息】 第一版
Function List	: 【主要函数及其功能】略...
1. -------
History			: 【历史修改记录】
--------------------------------------------------------------
<author>  |  <time>   |  <version >  |   <desc>
--------------------------------------------------------------
wang        2020/1/3      1.0     Data structures and function 
								  declarations
**************************************************************/
#pragma once
#include<stdio.h>
#include<stdlib.h>

/*堆栈所用的数据类型*/
#define DATA_TYPE int

/*链表数据结构*/
typedef struct LinkNode
{
	/*节点编号*/
	int id;   
	/*存储数据,可多个不同类型的值*/
	DATA_TYPE value;
	/*指向下一个节点的指针*/
	struct LinkNode* pNext;
}node,*PNODE;

/*--------------------------------------
 初始化
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE init(PNODE vPtrHead);

/*--------------------------------------
 压栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	int id				:节点编号
	DATA_TYPE data		:值
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE push(PNODE vPtrHead,int id,DATA_TYPE data);

/*--------------------------------------
 出栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	PNODE vPtrdata		:指定指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE pop(PNODE vPtrHead, PNODE vPtrdata);

/*--------------------------------------
 清空链表
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE clear(PNODE vPtrHead);

/*--------------------------------------
 展示所有数据
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
void show_All(PNODE vPtrHead);

/**************************************************************
FileName		: linkstack.c
Author			: wang
Version			: v1.0
Date			: 2020/1/3
Description		: 【模块描述】 链式正向栈源文件
Version			: 【版本信息】 第一版
Function List	: 【主要函数及其功能】略...
1. -------
History			: 【历史修改记录】无
--------------------------------------------------------------
<author>  |  <time>   |  <version >  |    <desc>
--------------------------------------------------------------
wang        2020/1/3      1.0         function implementations
***************************************************************/


#include"linkstack.h"

/*--------------------------------------
 初始化
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE init(PNODE vPtrHead)
{
	vPtrHead = NULL;
	return vPtrHead;
}

/*--------------------------------------
 压栈 链表尾部入栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	int id				:节点编号
	DATA_TYPE data		:值
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE push(PNODE vPtrHead, int id, DATA_TYPE data)
{
	PNODE vPtrNew = malloc(sizeof(node));
	if (vPtrNew != NULL)
	{
		vPtrNew->id = id;
		vPtrNew->value = data;
		vPtrNew->pNext = NULL;

		if (vPtrHead == NULL)
		{
			vPtrHead = vPtrNew;
		}
		else
		{
			PNODE vPtr_temp = vPtrHead;
			while (vPtr_temp->pNext!=NULL)
			{
				vPtr_temp = vPtr_temp->pNext;
			}
			vPtr_temp->pNext = vPtrNew;
		}
	}
	return vPtrHead;
}

/*--------------------------------------
 出栈,链表尾部出栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	PNODE vPtrdata		:出栈数据指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE pop(PNODE vPtrHead, PNODE vPtrdata)
{
	if (vPtrHead == NULL)
	{
		return NULL;
	}
	else if(vPtrHead->pNext==NULL)
	{
		vPtrdata->id = vPtrHead->id;
		vPtrdata->value = vPtrHead->value;
		free(vPtrHead);
		vPtrHead = NULL;
		return vPtrHead;
	}
	else
	{
		PNODE vPtr_temp = vPtrHead;
		while (vPtr_temp->pNext->pNext != NULL)//循环到倒数第二节点
		{
			vPtr_temp = vPtr_temp->pNext;
		}
		vPtrdata->id = vPtr_temp->pNext->id;
		vPtrdata->value = vPtr_temp->pNext->value;
		free(vPtr_temp->pNext);
		vPtr_temp->pNext = NULL;
		return vPtrHead;
	}
}

/*--------------------------------------
 清空链表
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE clear(PNODE vPtrHead)
{
	if (vPtrHead == NULL)
	{
		return NULL;
	}
	else
	{
		PNODE p1 = vPtrHead, p2 = NULL;
		while (p1->pNext!=NULL)
		{
			p2 = p1->pNext;
			p1->pNext = p2->pNext;
			free(p2);
		}
		free(p1);

		return vPtrHead = NULL;
	}
}

/*--------------------------------------
 展示所有数据
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
void show_All(PNODE vPtrHead)
{
	if (vPtrHead == NULL)
	{
		return;
	}
	else
	{
		printf("%s【%d】;%s【%d】;%s【%p】;%s【%p】\n",
			"节点编号:", vPtrHead->id,
			"节点数据:",vPtrHead->value,
			"节点地址:",vPtrHead,
			"下一节点:",vPtrHead->pNext);
		show_All(vPtrHead->pNext);
	}
}

调用示例:


#include"linkstack.h"

/*十进制转二进制*/
void decimalism_to_bianary(int num);

void main()
{
	int a = 556;

	decimalism_to_bianary(a);

	PNODE node_Head = NULL;
	node_Head = init(node_Head);
	printf("\n入栈\n");
	for (int i = 0; i < 10; i++)
	{
		node_Head = push(node_Head, i, i + 10);
	}

	show_All(node_Head);

	printf("\n出栈\n");
	while (node_Head!=NULL)
	{
		node nd;
		node_Head = pop(node_Head, &nd);
		printf("出栈数据:id=%d ; value=%d\n", nd.id, nd.value);
	}

	printf("\n\n进制转换\n\n");

	node_Head = init(node_Head);
	int index = 0;
	while (a)//压栈
	{
		node_Head = push(node_Head,index++, a % 2);
		a /= 2;
	}
	while (node_Head != NULL)
	{
		node nd;
		node_Head = pop(node_Head, &nd);
		printf("出栈数据:id=%d ; value=%d\n", nd.id, nd.value);
	}


	printf("\n\n出入同步 逆序输出\n\n");
	a = 556;
	index = 0;
	node_Head = clear(node_Head);
	while (a)//压栈
	{
		node_Head = push(node_Head, index++, a % 2);
		node nd;
		node_Head = pop(node_Head, &nd);
		printf("出栈数据:id=%d ; value=%d\n", nd.id, nd.value);

		a /= 2;
	}

	system("pause");
}


void decimalism_to_bianary(int num)
{
	if (num == 0)
	{
		return;
	}
	else
	{
		//printf("%d ", num % 2); //逆序输出
		decimalism_to_bianary(num / 2);
		printf("%d ", num % 2);//顺序输出
	}
}

 

链式反向栈 Dome

反向栈与正向栈的区别在于 :入栈和出栈顺序相反,反向栈从头入栈,从头出栈。正向栈从尾入栈,从尾出栈。反向栈的性能要比正向栈强,是因为操作不需要变量到栈尾。但是正向栈对数据统计和监控非常便利。在实际应用中,为了操作方便可以用反向栈,如果是监控数据用正向栈。

数据结构栈:手动分配,手动释放;内存栈:自动分配,自动释放。

/************************************************************
FileName		: linkstack.h
Author			: wang
Version			: v1.0
Date			: 2020/1/3
Description		: 【模块描述】 链式反向栈头文件
Version			: 【版本信息】 第一版
Function List	: 【主要函数及其功能】略...
1. -------
History			: 【历史修改记录】
--------------------------------------------------------------
<author>  |  <time>   |  <version >  |   <desc>
--------------------------------------------------------------
wang        2020/1/3      1.0     Data structures and function
								  declarations
**************************************************************/
#pragma once
#include<stdio.h>
#include<stdlib.h>

/*堆栈所用的数据类型*/
#define DATA_TYPE int

/*链表数据结构*/
typedef struct LinkNode
{
	/*节点编号*/
	int id;
	/*存储数据,可多个不同类型的值*/
	DATA_TYPE value;
	/*指向下一个节点的指针*/
	struct LinkNode* pNext;
}node, * PNODE;

/*--------------------------------------
 初始化
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE init(PNODE vPtrHead);

/*--------------------------------------
 压栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	int id				:节点编号
	DATA_TYPE data		:值
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE push(PNODE vPtrHead, int id, DATA_TYPE data);

/*--------------------------------------
 出栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	PNODE vPtrdata		:输出指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE pop(PNODE vPtrHead, PNODE vPtrdata);

/*--------------------------------------
 清空链表
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE clear(PNODE vPtrHead);

/*--------------------------------------
 展示所有数据
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
void show_All(PNODE vPtrHead);


/**************************************************************
FileName		: linkstack.c
Author			: wang
Version			: v1.0
Date			: 2020/1/3
Description		: 【模块描述】 链式反向栈源文件
Version			: 【版本信息】 第一版
Function List	: 【主要函数及其功能】略...
1. -------
History			: 【历史修改记录】无
--------------------------------------------------------------
<author>  |  <time>   |  <version >  |    <desc>
--------------------------------------------------------------
wang        2020/1/3      1.0         function implementations
***************************************************************/


#include"linkstack.h"

/*--------------------------------------
 初始化
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE init(PNODE vPtrHead)
{
	vPtrHead = NULL;
	return vPtrHead;
}

/*--------------------------------------
 压栈 链表头部入栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	int id				:节点编号
	DATA_TYPE data		:值
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE push(PNODE vPtrHead, int id, DATA_TYPE data)
{
	PNODE vPtrNew = malloc(sizeof(node));
	if (vPtrNew != NULL)
	{
		vPtrNew->id = id;
		vPtrNew->value = data;
		vPtrNew->pNext = NULL;

		if (vPtrHead == NULL)
		{
			vPtrHead = vPtrNew;
		}
		else
		{
			vPtrNew->pNext = vPtrHead;
			vPtrHead = vPtrNew;
		}
	}
	return vPtrHead;
}

/*--------------------------------------
 出栈,链表头部出栈
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
	PNODE vPtrdata		:出栈数据指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE pop(PNODE vPtrHead, PNODE vPtrdata)
{
	if (vPtrHead == NULL)
	{
		return NULL;
	}
	else if (vPtrHead->pNext == NULL)
	{
		vPtrdata->id = vPtrHead->id;
		vPtrdata->value = vPtrHead->value;
		free(vPtrHead);
		vPtrHead = NULL;
		return vPtrHead;
	}
	else
	{
		vPtrdata->id = vPtrHead->id;
		vPtrdata->value = vPtrHead->value;
		PNODE vPtr_temp = vPtrHead->pNext;
		free(vPtrHead);
		return vPtr_temp;
	}
}

/*--------------------------------------
 清空链表
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
PNODE clear(PNODE vPtrHead)
{
	if (vPtrHead == NULL)
	{
		return NULL;
	}
	else
	{
		PNODE p1 = vPtrHead, p2 = NULL;
		while (p1->pNext != NULL)
		{
			p2 = p1->pNext;
			p1->pNext = p2->pNext;
			free(p2);
		}
		free(p1);

		return vPtrHead = NULL;
	}
}

/*--------------------------------------
 展示所有数据
 ---------------------------------------
 参数:
	PNODE vPtrHead		:链表头指针
 ---------------------------------------
 返回:
	PNODE类型指针
---------------------------------------*/
void show_All(PNODE vPtrHead)
{
	if (vPtrHead == NULL)
	{
		return;
	}
	else
	{
		printf("%s【%d】;%s【%d】;%s【%p】;%s【%p】\n",
			"节点编号:", vPtrHead->id,
			"节点数据:", vPtrHead->value,
			"节点地址:", vPtrHead,
			"下一节点:", vPtrHead->pNext);
		show_All(vPtrHead->pNext);
	}
}

调用示例:

与上面调用代码相同。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值