栈的数据结构和基本操作2022-7-15

栈(stack)是限定仅在表尾进行插入和删除操作的线性表。

我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出(LastIn First Out)的线性表,简称LIFO结构。

理解栈的定义需要注意:

首先它是一个线性表,也就是说,栈元素具有线性关系,即前驱后继关系。只不过它是一种特殊的线性表而已。定义中说是在线性表的表尾进行插入和删除操作,这里表尾是指栈顶,而不是栈底。

关于链式栈和顺式栈比较

它们在时间复杂度上是一样的,均为O(1)。对于空间性能,顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题,但它的优势是存取时定位很方便,而链栈则要求每个元素都有指针域,这同时也增加了一些内存开销,但对于栈的长度无限制。所以它们的区别和线性表中讨论的一样,如果栈的使用过程中元素变化不可预料,有时很小,有时非常大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。

栈有什么应用?

系统借助栈的结构来实现递归。

递归函数前行阶段,对于每一层递归,函数的局部变量、参数值以及返回地址都被压入栈中。在退回阶段,位于栈顶的局部变量、参数值和返回地址被弹出,用于返回调用层次中执行代码的其余部分,也就是恢复了调用的状态。

由后缀表达式得到表达式树

我们一次一个符号地读人表达式。如果符号是操作数,那么我们就建立一个单节点树并将一个指向它的指针推人栈中。如果符号是操作符,那么我们就从栈中弹出指向两棵树 T 和 T 的那两个觜针( T 的先弹出)并形成一棵新的树,该树的根就是操作符,它的左、右儿子分别指向 T :和 T 。然后将指向这棵新树的指针压人栈中。这样就能得到后缀表达式对应的表达式树。

中缀表达式转后缀表达式

栈的数据结构和基本操作的定义:(用C描述)(链式)

具体完整代码:

stack.h

#pragma once

#ifndef STACK_H


#include<stdio.h>
#include<stdlib.h>

struct node;
typedef struct node* PtrToNode;
typedef struct node* Stack;  //栈


Stack createStack();   //创建一个栈
void disposeStack(Stack stack);   //销毁栈
void makeStackEmpty(Stack stack);   //清空栈
bool IsEmpty(Stack stack);  //判断是否为空栈
void Pop(Stack stack);  //出栈
void Push(Stack stack, int value);  //入栈
int TopValue(Stack stack);  //取栈顶元素
PtrToNode Top(Stack stack);  //取栈顶
void printStack(Stack stack);  //从栈打印栈


#endif

stack.c

#include<stdio.h>
#include<stdlib.h>
#include"Stack.h"


typedef struct node {
	int value;
	PtrToNode next;
}Node;

//创建栈
Stack createStack()
{
	Stack stack = (Stack)malloc(sizeof(Node));
	stack->next = NULL;
	return Stack();
}

//销毁栈
void disposeStack(Stack stack) {
	makeStackEmpty(stack);
	free(stack);
}

//清空栈
void makeStackEmpty(Stack stack) {
	if (!IsEmpty(stack)) {
		Pop(stack);
		makeStackEmpty(stack);
	}
}


//判断是否为空栈
bool IsEmpty(Stack stack) {
	return stack->next == NULL;
}

//出栈
void Pop(Stack stack) {
	if (!IsEmpty(stack)) {
		PtrToNode out = stack->next;
		stack->next = out->next;
		free(out);
	}
}

//入栈
void Push(Stack stack, int value) {
	PtrToNode node = (PtrToNode)malloc(sizeof(Node));
	node->value = value;
	if (stack->next == NULL) {
		stack->next = node;
		node->next = NULL;
	}
	else {
		node->next = stack->next->next;
		stack->next = node;
	}
}

//取栈顶元素
int TopValue(Stack stack) {
	if (!IsEmpty(stack)) {
		return stack->next->value;
	}
	else
		return 0;
}

//取栈顶
PtrToNode Top(Stack stack) {
	if (!IsEmpty(stack)) {
		return stack->next;
	}
	else
		return NULL;
}

//
void printStack(Stack stack) {
	if (!IsEmpty(stack)) {
		PtrToNode move = stack->next;
		while (move != NULL) {
			printf("%d", move->value);
			move = move->next;
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快阁东西倚晚晴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值