堆栈(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);
}
}
调用示例:
与上面调用代码相同。