IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 栈详解(顺序栈和链栈) -> 正文阅读

[数据结构与算法]栈详解(顺序栈和链栈)

什么是栈?

栈是一种基本数据结构,因其拥有后进先出的特点(Last in First out),也就是LIFO,栈的一种常见用途就是用来判断一串字符中的括号是否有效。
括号的类型有{}、[]、(),“{[]}”像这样的就是有效的,而像"{[])"这样的就是无效的括号,这通常用于编译器的语法检查。
在内存的中使用也是一种栈,因函数调用会压栈,每调用一次压栈一次,当递归层次太深时,我们经常看到编译器报错:“Stack Overflow”,也就是栈溢出。
栈的主要操作有Push和Pop,入栈和出栈。
栈有俩种实现方法,一种是通过数组,另一种是通过链表。
使用数组实现的查询效率高,易于实现。缺点是想要插入元素困难,而且受限于数组大小。
使用链表的建立易于插入且不用受限于大小,因为每次压栈都会向堆区申请内存。缺点是查询困难,空间成本高。(因为使用了malloc)

顺序栈

先定义数据结构

#define size 100
typedef struct Stack
{
	int arr[size];
	int top;//指针
}stack;

函数声明

void InitStack(stack* stack);//初始化
int Push(stack* stack, int* e);//入栈
int Pop(stack* stack, int* e);//出栈
int GetTop(stack* stack, int* e);//获取栈顶元素

栈初始化函数

void InitStack(stack* stack)
{
	stack->top = -1;
}

Push

int Push(stack* stack,int e)//压栈
{
	if (stack->top == size - 1)//判断是否满栈
	{
		printf("栈满!\n");
		return 0 ;//失败返回零
	}
	else
	{
		stack->top++;//每次入栈,指针向后移动
		stack->arr[stack->top] = e;
		return 1;//成功则返回1
	}
}

Pop

int Pop(stack* stack, int* e)//出栈
{
	if (stack->top == -1)//判断是否为空
	{
		printf("栈空!\n");
		return 0;//出栈失败返回零
	}
	else
	{
		*e = stack->arr[stack->top];
			stack->top--;//每次出栈指针向前移动
			return 1;//出栈成功返回1
	}

}

GetTop

int GetTop(stack* stack, int* e)//获取栈顶元素
{
	if (stack->top == -1)
	{
		printf("栈空!\n");//判断是否为空
		return;
	}
	else
	{
		*e = stack->arr[stack->top];//只获取栈顶元素,top不变
		return 1;
	}
}

链栈

链栈和顺序栈区别在于一个使用链表实现,另一个使用数组实现。
链栈其主要操作也是Push和Pop
先定义类型

typedef struct Stack
{
	int data;
	struct Stack* next;
}LinkStack;

函数声明

LinkStack* CreatStack();
void LPush(LinkStack* stack, int e);
int LPop(LinkStack* stack, int* e);
int LGetnext(LinkStack* stack, int e);
void LJudgeNull(LinkStack* stack);

首先建立栈

LinkStack* CreatStack()
{     
    LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));
    stack->next = NULL;//初始化
    return stack;
}

入栈操作,这里需要注意的是,栈是从高地址到低地址,而不是低地址到高地址。有兴趣可以看下。通过观察,我们可以从编译器中看到,压栈是先使用高地址,再使用低地址。
函数栈帧 :局部变量的创建与销毁? 函数的调用? 传参的形式?
在这里插入图片描述

void  LPush(LinkStack* stack, int e)//入栈
{  
   
     LinkStack* p;
     p = (LinkStack*)malloc(sizeof(LinkStack));//新建节点p
     p->data = e;
     p->next = stack->next;//将p与下一级链接
     stack->next = p;//指向栈顶
    
    
}

出栈

int  LPop(LinkStack* stack, int* e)
{
    if (stack->next == NULL)
    {
        printf("栈空!\n");
        return 0;
    }
    else//出栈
    {  
        *e = stack->next->data;
        LinkStack* p = stack->next;
        stack->next = stack->next->next;//指向栈顶
        free(p);
    }
    return 1;
}

判空

void LJudgeNull(LinkStack* stack)//判空
{
    if (stack->next == NULL)
    {
        printf("栈空!\n");
        return;
    }
}

取出栈顶值

void LGetTop(LinkStack* stack,int*e )//取栈顶值
{
    if (stack->next == NULL)
    {
        printf("栈空!\n");
        return;
    }
    else
    {
        *e = stack->next->data;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:28:44  更:2021-08-09 10:30:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:49:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码