栈空间
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函数中并未进行函数调用,请谅解。