栈空间的讲解

栈空间

1. 写在前面
本人是一名西南交通大学2020级自动化专业的学生,由于本人最近正在学习数据结构,遂想在此陈述一下对线性表与链表的个人理解。这篇博客主要参考了清华大学出版社的《数据结构C语言版》,其他的很多地方也补充了一些个人理解,读起来不那么官方和专业,如有不当之处希望各位大佬们多多指教.
2. 对栈空间的介绍
计算机的内存空间分为堆区,栈区和静态区。堆区用于分配malloc或realloc函数所开辟的内存空间,而这些空间需要用free函数对所开辟的空间进行释放,否则会使计算机内存急剧下降,甚至造成死机。而栈空间则用于数据的存储,栈是一种受限制的线性表,限定仅在表尾进行插入和删除操作的线性表。而表尾这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。栈是一种特殊的链式存储结构,入栈和出栈的方向是相反的。
3. 利用栈空间进行数据存储
在了解完栈空间后我们接下来讲解栈空间的创建与使用。栈空间有两种实现方式:1.线性表(即线性存储)2.链表(即链式存储结构)。线性存储结构和线性表的使用其实是一样的,而线性表在上一篇文章中已经陈述过了这里便不再赘述。接下来我们讲解一下链式存储结构。在链表中我们知道,链表分为数据域与指针域,所以在这里我们先创建指针域与数据域。
代码如下:

struct Node   //定义了栈空间中的一个数据单元Node
{
	int data;     //数据域
	struct Node* next;//指针域
};

接下来我们创建链表的结点,代码如下:

//创建结点
//创建结点
struct Node* CreateNode(int data)//返回值是struct Node*类型的指针变量 即数据单元节点地址
{
	struct Node* NewNode=(struct Node*)malloc(sizeof(struct Node));
	NewNode->data=0;
	NewNode->next=NULL;
	return NewNode;   //返回一个数据单元节点地址
}

接下来我们创建一个栈空间:

struct stack    //创建栈空间
{
	struct Node* StackTop; //定义栈首地址
	int size;
};

4. 对栈空间进行函数操作
1.栈的初始化
首先用malloc函数开辟一段内存空间(注意这段内存空间其实在堆区,所以栈又叫做堆栈)。接下来我们对栈空间进行初始化:使栈顶地址指向为空,并使size=0。

//栈的初始化(即栈的创建)
struct stack* CreateStack()
{
	struct stack* NewStack=(struct stack*)malloc(sizeof(struct stack));//开辟了空间
	NewStack->StackTop=NULL;  //栈顶地址
	NewStack->size=0;
	return NewStack;  //返回一个初始栈
}

2.入栈
即完成地址链接:NewNode的地址链接到栈首地址,接下来使栈首地址指向New Node数据块的结点从而实现链接。

//入栈
void Push(struct stack* NewStack,int data)//这个函数中传入的是初始化后的栈
{
	struct Node* NewNode=CreateNode(data);
	NewNode->next=NewStack->StackTop;//完成地址链接:NewNode的地址链接到栈首地址
	NewStack->StackTop=NewNode;
	NewStack->size++;
}

3.获取栈顶元素
直接取出栈顶元素data去的数据即可。

int top(struct stack* NewStack)
{
	if(NewStack->size==0)
	{
		printf("栈为空,错误!\n");
		return NewStack->size;
	}
	else
		return NewStack->StackTop->data;
}

4.出栈
将栈顶元素的首地址后移,将栈顶元素的next区的地址赋给NewNode的结点,从而完成栈顶的后移,接着用free函数释放栈顶元素的地址。

int pop(struct stack* NewStack)
{
	if(NewStack->size==0)
	{
		printf("栈为空,错误!\n");
		return NewStack->size;
	}
	else
	{
	   struct Node* NewNode=NewStack->StackTop->next;
	   free(NewStack->StackTop);
	   NewStack->size--;
	   return NewNode->data;
	}
}

5.接下来介绍一个很好用的函数:判空函数,如果链表的size返回值为0,则为一个空表。

int Empty(struct stack* NewStack)
{
	if(NewStack->size==0)
		return 0;
	else
		return 1;
}

5. 所有操作函数

#include<stdio.h>
#include<stdlib.h>
struct Node   //定义了栈空间中的一个数据单元Node
{
	int data;     //数据域
	struct Node* next;//指针域
};
struct stack    //创建栈空间
{
	struct Node* StackTop; //定义栈首地址
	int size;
};
//创建结点
struct Node* CreateNode(int data)//返回值是struct Node*类型的指针变量 即数据单元节点地址
{
	struct Node* NewNode=(struct Node*)malloc(sizeof(struct Node));
	NewNode->data=0;
	NewNode->next=NULL;
	return NewNode;   //返回一个数据单元节点地址
}
//栈的初始化(即栈的创建)
struct stack* CreateStack()
{
	struct stack* NewStack=(struct stack*)malloc(sizeof(struct stack));//开辟了空间
	NewStack->StackTop=NULL;  //栈顶地址
	NewStack->size=0;
	return NewStack;  //返回一个初始栈
}
//入栈
void Push(struct stack* NewStack,int data)//这个函数中传入的是初始化后的栈
{
	struct Node* NewNode=CreateNode(data);
	NewNode->next=NewStack->StackTop;//完成地址链接:NewNode的地址链接到栈首地址
	NewStack->StackTop=NewNode;
	NewStack->size++;
}
//获取栈顶元素
int top(struct stack* NewStack)
{
	if(NewStack->size==0)
	{
		printf("栈为空,错误!\n");
		return NewStack->size;
	}
	else
		return NewStack->StackTop->data;
}
//出栈
int pop(struct stack* NewStack)
{
	if(NewStack->size==0)
	{
		printf("栈为空,错误!\n");
		return NewStack->size;
	}
	else
	{
	   struct Node* NewNode=NewStack->StackTop->next;
	   free(NewStack->StackTop);
	   NewStack->size--;
	   return NewNode->data;
	}
}
int Empty(struct stack* NewStack)
{
	if(NewStack->size==0)
		return 0;
	else
		return 1;
}
 
int main()
{
	return 0;
}

还是和上次一样,我的main函数中并未进行函数调用,请谅解。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值