最近在工作之余,回过头来研究数据结构,发现以前对数据结构的认识依然处于非常浅显的状态,于是决定从最简单的代码开始重新学习数据结构,并在此记录下学习的历程,与大家分享
第一段代码用C语言实现最基本的数据结构,栈
这个栈是通过数组实现的,我们可以称为顺序栈
主要作用是对栈的结构和工作方式有了一个初步的,直观的认识
代码在vs2017编译通过
//2018/12/19 from 朱宏江
//此代码使用C语言,基于数组的方式实现数据结构 栈(stack)
//这是栈的最浅显,最基础的实现方式,带我们了解栈的工作方式
//#define MAXSIZE 10
//栈的结构定义
typedef struct {
int data[10];
int top = 0; //用于栈顶指针
}SqStack;
//入栈函数 插入e为新的栈顶元素
void Push(SqStack* S, int e)
{
S->data[S->top] = e;
S->top++;
}
//出栈函数 若栈不空,则删除S的栈顶元素,用e返回其值,并返回真,否则返回假
void Pop(SqStack* S, int* e)
{
S->top--; //栈顶指针减1
*e = S->data[S->top]; //将要删除的栈顶元素赋值给e
}
int main(int argv, char** argc)
{
SqStack* Stack = (SqStack*)malloc(sizeof(SqStack));
//初始化
memset(Stack, 0, sizeof(SqStack));
//循环入栈
for (int i = 0; i < 10; i++)
{
Push(Stack, i);
}
int num = 0;
int* p_num = #
for (int i = 0; i < 10; i++)
{
Pop(Stack, p_num);
printf("%d \n", *p_num);
}
//std::cin.get();
return 0;
}
运行结果如图:
栈的链式存储结构实现方法也可以通过链表
用链表的方式实现了栈的链式存储结构,简称为链栈
栈的栈顶用于Push和Pop操作,由于单项链表有头指针,同时栈有栈顶指针,所以将头指针当做栈顶指针,同时将链表头部作为栈顶
同时,链栈不需要链表的头结点
此段代码通过vs2017环境编译,代码如下
//2018/12/19 from朱宏江
//此段代码基于C++,使用链表的方式实现了栈的链式存储结构
#include <iostream>
typedef struct StackNode
{
int data;
struct StackNode* next;
}StackNode;
class LinkStack
{
public:
LinkStack() :top(nullptr), cont(0) {}
~LinkStack() {}
public:
void Push(LinkStack* S, int e)
{
StackNode* stack = (StackNode*)malloc(sizeof(StackNode));
memset(stack, 0, sizeof(StackNode));
stack->data = e;
stack->next = S->top;
S->top = stack;
S->cont++;
std::cout << e << " 入栈" << std::endl;
return;
}
void Pop(LinkStack* S, int* e)
{
StackNode* p = nullptr;
if (StackEmpty(S) == true)
{
std::cout << "栈空" << std::endl;
return;
}
*e = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
S->cont--;
return;
}
bool StackEmpty(LinkStack* S)
{
if (S->cont == 0)
{
S->top = nullptr;
return true;
}
else
return false;
}
private:
StackNode* top;
int cont;
};
int main(int argc, char** argv)
{
LinkStack* S = new LinkStack{};
for (int i = 0; i < 10; i++)
{
S->Push(S, i);
}
int num = 0;
int* p_num = #
for (int i = 0; i < 10; i++)
{
S->Pop(S, p_num);
std::cout << *p_num << " 出栈" << std::endl;
}
std::cin.get();
return 0;
}
运行结果如图:
顺序栈与链栈的时间复杂度上是相同的
不同的是,顺序栈需要预先确定一个长度,可能存在内存浪费的问题,优势是存取时定位快捷,链栈的存储单元存在指针域,会增大内存开销,但是长度几乎是无限制的,这些优缺点决定他们的使用由现实的需要来确定.