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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构之Stack -> 正文阅读

[数据结构与算法]数据结构之Stack


一、Stack的基本概念

栈是一种特殊的i线性表
栈仅能在线性表的一端进行操作
??栈顶(Top):允许操作的一端
??栈底(Bottom):不允许操作的一端

在这里插入图片描述



二、Stack的常用操作


??创建栈
??销毁栈
??清空栈
??出栈
??获取站的元素大小
//C语言描述 ====>> 栈的实现与设计
#ifndef _MY_STACK_H_
#define _MY_STACK_H_

typedef void Stack;

Stack* Stack_Create();

void Stack_Destroy(Stack* stack);

void Stack_Clear(Stack* stack);

int Stack_Push(Stack* stack, void* item);

void* Stack_Pop(Stack* stack);

void* Stack_Top(Stack* stack);

int Stack_Size(Stack* stack);

#endif //_MY_STACK_H_



三、栈模型和链表模型关系分析

在这里插入图片描述

模拟栈的线性存储:
??线性表的顺序储蓄来模拟栈时,在尾部添加或删除大量元素,不会造成大数组的元素大量移动,所以在尾部插入删除元素比较好。
??用线性表的链式存储栈的线性存储时,在链表头部插入元素或删除元素,不会因寻找链表尾节点而造成大规模遍历链表节点,所以在链表头部插入删除元素比较好。


四、栈的顺序存储设计与实现

基本概念

在这里插入图片描述

设计与实现

//头文件
#ifndef  __MY_SEQLIST_H__ 
#define __MY_SEQLIST_H__

typedef void SeqList;
typedef void SeqListNode;

SeqList* SeqStack_Create(int capacity);

void SeqStack _Destroy(SeqStack * list);

void SeqStack _Clear(SeqStack * list);

int SeqStack _Length(SeqStack * list);

int SeqStack _Capacity(SeqStack * list);

int SeqStack _Insert(SeqStack * list, SeqListNode* node, int pos);

SeqListNode* SeqList_Get(SeqList* list, int pos);

SeqListNode* SeqList_Delete(SeqList* list, int pos);

#endif  //__MY_SEQLIST_H__


五、栈的链式存储设计与实现

基本概念

在这里插入图片描述

设计与实现

//头文件
#ifndef _MY_LINKSTACK_H_
#define _MY_LINKSTACK_H_

typedef void LinkStack;

LinkStack* LinkStack_Create();

void LinkStack_Destroy(LinkStack* stack);

void LinkStack_Clear(LinkStack* stack);

int LinkStack_Push(LinkStack* stack, void* item);

void* LinkStack_Pop(LinkStack* stack);

void* LinkStack_Top(LinkStack* stack);

int LinkStack_Size(LinkStack* stack);

#endif //_MY_LINKSTACK_H_


六 、栈的应用

就近匹配

几乎所有的编译器都具有检车括号是否匹配的能力
如何实现编译器中的符号成对检测?

算法思路:
??当遇见第一个字符开始扫描
??当遇见普通字符时忽略
??当遇见左括号压入栈中
??当遇见右符号从栈中弹出符号,并进行匹配
????匹配成功:继续读入下一字节
????匹配失败:立刻停止,并报错
结束
??成功:所有字符扫描完毕,且栈为空
??失败:匹配失败或所有字符扫描完毕但栈非空

当需要检测成对出现但又互不相邻的事物时
可以使用栈“后进先出”的特性
栈非常适合于需要“就近匹配”的场合
//就近匹配
#include <iostream>
#include <stack>
using namespace std;

#if 0
// 判断左括号
bool isLeft(char c)
{
	bool bl;
	switch (c)
	{
	case '[':
	case '(':
	case '{':
	case '<':
		bl = true;
		break;
	default:
		bl = false;
		break;
	}
	return bl;
}

bool isRight(char c)
{
	bool bl;
	switch (c)
	{
	case ']':
	case ')':
	case '}':
	case '>':
		bl = true;
		break;
	default:
		bl = false;
		break;
	}
	return bl;
}

bool match(char left, char right)
{
	bool bl;
	switch (left)
	{
	case '[':
		bl = right == ']';
		break;
	case '(':
		bl = right == ')';
		break;
	case '{':
		bl = right == '}';
		break;
	case '<':
		bl = right == '>';
		break;
	default:
		bl = false;
		break;
	}
	return bl;
}


void Jiujinpipei(const char* p)
{
	int i = 0;
	stack<char> st;
	while (p[i] != '\0')
	{
		// 如果是左括号
		if (isLeft(p[i]))
		{
			// 压栈
			st.push(p[i]);
		}
		// 右括号
		else if (isRight(p[i]))
		{
			if (!st.empty())
			{
				// 栈顶符号
				char top = st.top();
				// 匹配
				if (!match(top, p[i]))
				{
					cout << "匹配失败!" << endl;
					break;
				}
				st.pop();
			}
			else
			{
				cout << "缺少左括号..." << endl;
				break;
			}
		}
		i++;
	}
	if (p[i] == '\0' && st.empty())
	{
		cout << "匹配成功了...." << endl;
	}
	else
	{
		cout << "匹配失败!!!" << endl;
	}
}

void main()
{
	// 
	Jiujinpipei("#include <stdio.h> int main()  int a[4][4]; int (*p)[4]; p = a[0]; return 0;}");
	system("pause");
}

#endif;

中缀表达式和后缀表达式

??计算机的本质工作就是做数学运算,那计算机可以读入字符串 “9 + (3 - 1) * 5 + 8 / 2”并计算值吗?
??后缀表达式 ==? 符合计算机逻辑
??波兰科学家在20世纪50年代提出一种将运算符刚在数学的后缀表达式对应的,我们习惯的数学表达式叫中缀表达式 ===》 符合人类思考习惯
实例:
??5 + 4=> 5 4 +
??1 + 2 * 3 => 1 2 3 * +
??8 + ( 3 – 1 ) * 5 => 8 3 1 – 5 * +
??中缀表达式符合人类的阅读和思维习惯;获罪表达式符合计算机的“运算习惯”。所以,如何将中缀表达式转换成后缀表达式?

中缀转后缀算法:
??遍历中缀表达式中的数字和符号
??对于数字,直接输出
??对于符号:
????左括号:进栈
????运算符号:与栈顶符号进行优先级比较
??????若栈顶符号优先级低:此符合进栈(默认进栈若是左括号,左括号优先级最低)
??????若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈
????右括号:将栈顶符号弹出并输出,直到匹配左括号
??遍历效果:将栈顶的所有符号弹出并输出
//中缀转后缀.cpp
#include<iostream>
#include<stack>
#include <cstring>
using namespace std;

#if 1



bool isNumber(char c)
{
	return c >= '0' && c <= '9';
}

bool isOperator(char c)
{
	return c == '+' || c == '-' || c == '*' || c == '/';
}

bool isLeft(char c)
{
	return c == '(';
}

bool isRight(char c)
{
	return c == ')';
}

int priority(char c)
{
	int ret = 0;
	switch (c)
	{
	case '+':
	case '_':
		ret = 1;
		break;
	case '*':
	case '/':
		ret = 2;
		break;
	default:
		break;
	}
	return ret;
}

void Transform(const char* p)
{
	int i = 0;
	stack<char> st;
	while (p[i] != '\0')
	{
		//数字
		if (isNumber(p[i]))
		{
			// 直接输出
			cout << p[i];
		}	
		//左括号
		if (isLeft(p[i]))
		{
			//进栈
			st.push(p[i]);
		}
		//运算符
		else if (isOperator(p[i]))
		{
			//优先级比较
			while (!st.empty() && (priority(p[i]<=priority(st.top()))))
			{
				//输出
				cout << st.top();
				
				//出栈
				st.pop();
			}
			//进栈
			st.push(p[i]);
		}
		//右括号
		else if (isRight(p[i]))
		{
			//如果不是左括号 输出并弹出
			while (!isLeft(st.top()))
			{
				//输出
				cout << st.top();

				//出栈
				st.pop();
			}

			//左括号出栈
			st.pop();
		}
			
			i++;
	}

	//弹出栈内剩余符号
	while (!st.empty())
	{
		//输出
		cout << st.top();

		//出栈
		st.pop();
	}
}

void main()
{
	string str;
	cin >> str;
	Transform(str.data());
	system("pause");
}

#endif // 1

计算机是如何基于后缀表达式计算的?
对于数字:进栈
对于符号: ??从栈中弹出右操作数
??从栈中弹出左操作数
?l?根据符号进行运算
??将运算结果压入栈中
遍历结果:栈中唯一数字作为计算结果

在这里插入图片描述

栈的神奇!
??中缀表达式是人习惯的表达方式
??后缀表达式是计算机喜欢的表达方式
??通过栈可以方便的将中缀形式变换位后缀形式
??中缀表达式的计算过程类似程序编译运行的过程



  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-23 12:44:52  更:2021-10-23 12:45:53 
 
开发: 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/26 8:31:23-

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