数据结构:栈的链式实现(C语言描述)

栈本质上是一个线性表,只不过对线性表的操作进行了限制,只可以在表的一端进行操作(插入、删除元素)。栈是一种是一种实现数据“先进后出”的存储结构,分为静态栈和动态栈,静态栈就是以数组的方式存储数据,动态栈是以链表的方式存储数据;对栈的操作算法,常用的就是压栈和出;下面将以链式的方式创建栈,并对用c语言实现栈的压栈和出栈的算法:

1.栈的创建

    在创建一个数据结构之前,必须知道这种数据结构由哪些参数组成,栈的本质既然是个链表,它必然由很多节点组成;为了实现“先进后出”这种数据结构,我们需要引进两个参数,一个是栈顶指针(pTop),始终指向栈顶元素。一个参数是栈底指针(pBottom),始终指向栈底元素。我们知道为了方便描述链表的各种操作,引进了头节点的概念,即为每个链表前面加一个头节点,但并存放有效数据;同样,为了实现栈的操作,我们同样需要一个不存放任何有效数据的节点,并且栈底指针始终指向该节点;

typedef int elementype;
//定义一个节点
typedef struct Node
{
	elementype data;
	struct Node *pNext;
}NODE,*PNODE;//
//构造一个栈
typedef struct stack
{
	PNODE pTop; //栈顶指针
	PNODE pBottom;//栈底指针
}STACK,*PSTACK;
其中,使用了typedef关键词,typedef只是给一个数据类型提供一个别名;因此这里的NODE=struct Node ,PNODE=struct Node *;同样,STACK=struct stack ,PSTACK=struct Node *;

此时,数据类型构造出来了,接下来要创建一个空栈,这样我们才能进行栈的操作,创建栈,无非就是分配内存,内存分配有三种方式,静态存储区,栈,堆;

//创建一个空栈,里面没有任何有效数据;
void Create_Stack(PSTACK S)
{
	S->pBottom=(struct Node *)malloc(sizeof(struct Node));
	if(NULL==S->pBottom)
	{
		printf("Memory allocation failure");
		exit(-1);
	}
	S->pTop=S->pBottom;
	S->pTop->data=0;
	S->pTop->pNext=NULL;  //防止出现野指针
}

图1 空栈示意图

2.压栈算法


图2 压栈算法示意图

压栈的伪算法:
(1).创建一个节点p,并修改节点的指针域使其指向栈顶数据元素;p->pNext=pTop;
(2)修改栈顶指针,使其指向栈顶元素,pTop=p;

程序代码:

//进栈
void Push_Stack(PSTACK S,int val)
{
	PNODE p=(struct Node *)malloc(sizeof(struct Node));
	if(NULL==p)
	{
		printf("Memory allocation failure");
		exit(-1);
	}
	p->data=val;
	p->pNext=S->pTop;  //让p的指针域指向上一个节点
	S->pTop=p;        //让pTop指针指向栈顶元素
}

3.出栈算法


图3.出栈算法示意图

出栈伪算法:
(1).先用P指针保存要删除数据的地址,用于便于释放此节点的内存,即p=pTop;
(2).修改栈顶指针的指向,使其指向栈顶元素;pTop=pTop->pNext;

附录:程序代码

stack.h文件代码:

#ifndef __STACK_H_
#define __STACK_H_
typedef int elementype;
//定义一个节点
typedef struct Node
{
	elementype data;
	struct Node *pNext;
}NODE,*PNODE;//
//构造一个栈
typedef struct stack
{
	PNODE pTop; //栈顶指针
	PNODE pBottom;//栈底指针
}STACK,*PSTACK;
//函数声明区
void Create_Stack(PSTACK S);
void Push_Stack(PSTACK S,int val);
bool Pop_Stack(PSTACK S,int *val);
void Traverse_Stack(PSTACK S);
void Clear_Stack(PSTACK S);
#endif

stack.c文件代码:

#include<stdio.h>
#include<stdlib.h>
#include"stack.h"
//创建一个空栈,里面没有任何有效数据;
void Create_Stack(PSTACK S)
{
	S->pBottom=(struct Node *)malloc(sizeof(struct Node));
	if(NULL==S->pBottom)
	{
		printf("Memory allocation failure");
		exit(-1);
	}
	S->pTop=S->pBottom;
	S->pTop->data=0;
	S->pTop->pNext=NULL;  //防止出现野指针
}
//进栈
void Push_Stack(PSTACK S,int val)
{
	PNODE p=(struct Node *)malloc(sizeof(struct Node));
	if(NULL==p)
	{
		printf("Memory allocation failure");
		exit(-1);
	}
	p->data=val;
	p->pNext=S->pTop;  //让p的指针域指向上一个节点
	S->pTop=p;        //让pTop指针指向栈顶元素
}
//打印出栈里面的元素
void Traverse_Stack(PSTACK S)
{
	PNODE p=S->pTop;
	printf("栈中的元素是:\n");
	while(p!=S->pBottom)
	{
		printf("%d ",p->data);
		p=p->pNext;
	}
	printf("\n");
}
bool Is_Empty(PSTACK pS)
{
	if (pS->pTop == pS->pBottom)
		return true;
	else
		return false;
}
bool Pop_Stack(PSTACK S,int *val)
{
	if(Is_Empty(S))
		return false;
	else
	{
	    PNODE p=S->pTop;
		*val=S->pTop->data;
		S->pTop=S->pTop->pNext;  //使pTop指针指向栈顶元素;
		free(p);  //释放p指针所指向的那个节点的内存;
		p=NULL;   //要养成好的习惯;
		return true;
	}
}
void Clear_Stack(PSTACK S)
{
	if(Is_Empty(S))
		return;
	else
	{
		PNODE p=NULL;  //养成一好习惯,定义指针记得初始化;
		while(S->pTop!=S->pBottom)
		{
			p=S->pTop;
			S->pTop=S->pTop->pNext;
			free(p);
			p=NULL;
		}

	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值