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 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 顺序栈与链式栈 -> 正文阅读

[C++知识库]顺序栈与链式栈

目录

1.顺序栈

2.算法3.1数制的转换

3.算法3.2括号匹配

4.算法3.3链式栈解决表达式求值

5.算法3.4舞伴问题

6.算法3.5汉诺塔问题


1.顺序栈

#include <iostream>
#include<stdio.h>
using namespace std;
#define SElemType int
#define Status int
#define STACK_INIT_SIZE 100
#define STACKINCREMENT  10

typedef struct {
	SElemType* base; //栈底
	SElemType* top;  //栈顶
	int stacksize;
}SqStack;

Status InitStack(SqStack  &s)
{
	s.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));
		if (!s.base)
			exit(_OVERFLOW);
		s.top = s.base;
		s.stacksize = STACK_INIT_SIZE;
		return 1;
}

Status DestoryStack(SqStack &s)
{
	free(s.base);
	s.base = NULL;
	s.top = NULL;
	s.stacksize = 0;
	return 1;
}

Status ClearStack(SqStack& s)
{
	if (!s.base)
		return 0;
	s.top = s.base;
	return 1;
}

Status StackEmpty(SqStack s)
{
	if (s.top == s.base)
		return 1;
	return 0;
}

Status StackLength(SqStack s)
{
	if (!s.base)
		return 0;
	return (int)(s.top - s.base);
}

Status GetTop(SqStack s, SElemType& e)
{
	if (s.base == s.top)
		return 0;
	e = *(s.top - 1);
	return 1;
}

Status Push(SqStack& s, SElemType e)
{
	if (!s.base)
		return 0;
	if (s.top - s.base >= s.stacksize)
	{
		s.base = (SElemType*)realloc(s.base, (s.stacksize + STACKINCREMENT) * sizeof(SElemType));
		if (!s.base)
			exit(_OVERFLOW);
		s.top = s.base + s.stacksize;
		s.stacksize += STACKINCREMENT;
	}
	*s.top++ = e;
	return 1;
}

Status Pop(SqStack& s, SElemType& e)
{
	if (!s.base || s.top == s.base)
		return 0;
	e = *--s.top;
	return 1;
}

void visit(SElemType e)
{
	cout << e << " ";
}

Status StackTraverse(SqStack s, void(*visit)(SElemType))
{
	SElemType* p = s.base;
	if (!s.base)
		return 0;
	while (p < s.top)
		visit(*p++);
	cout << "\n";
	return 1;
}

2.算法3.1数制的转换

void conversion()
{
	SqStack S;
	InitStack(S);
	SElemType N, e;
	scanf_s("%d", &N);
	while (N)
	{
		Push(S, N % 8);
		N /= 8;
	}
	while (!StackEmpty(S))
	{
		Pop(S, e);
		cout << e;
	}
}

3.算法3.2括号匹配

void LineEdit()
{
	SqStack S;
	InitStack(S);
	SElemType c;
	char ch = getchar();
	while(ch != EOF)
	{
		while (ch != EOF && ch != '\n')
		{
			switch (ch)
			{
			case '#':
				Pop(S, c);
				break;
			case '@':
				ClearStack(S);
				break;
			default:
				Push(S, ch);
			}
			ch = getchar();
		}
		ClearStack(S);
		if (ch != EOF)
			ch = getchar();
	}
	DestoryStack(S);
}

4.算法3.3链式栈解决表达式求值

 #include <iostream>
using namespace std;
#define SElemType char
#define Status int
typedef char OperandType;

typedef struct SNode
{
	SElemType data;
	struct SNode* next;
}SNode, * LinkStack;

Status InitStack(LinkStack& S)
{
	S = (LinkStack)malloc(sizeof(SNode));
	if (!S)
		exit(_OVERFLOW);
	S->next = NULL;
	return 1;
}

Status DestroyStack(LinkStack& S)
{
	LinkStack p = S->next, ptmp;//p指向栈顶
	while (p)                  //p指向栈底时,循环停止
	{
		ptmp = p->next;
		free(p);               //释放每个数据节点的指针域
		p = ptmp;
	}
	free(S);
	return 1;
}

Status ClearStack(LinkStack& S)
{
	LinkStack p = S->next, ptmp;  //p指向栈顶
	while (p)
	{
		ptmp = p->next;
		free(p);
		p = ptmp;
	}
	S->next = NULL;
	return 1;
}

Status StackEmpty(LinkStack S)
{
	if (S->next == NULL)
		return 1;
	else
		return 0;
}

int  StackLength(LinkStack S)
{
	int n = 0;
	LinkStack p = S->next;
	while (p)
	{
		n++;
		p = p->next;
	}
	return  n;
}

Status GetTop(LinkStack S, SElemType& e)
{
	if (S->next == NULL)
		return 0;
	e = S->next->data;    //取栈顶元素
	return 1;
}

Status Push(LinkStack& S, SElemType e)
{
	LinkStack p = (LinkStack)malloc(sizeof(SNode));
	p->data = e;
	p->next = S->next;            //新结点指向栈顶
	S->next = p;                  //更新栈顶指针

	return 1;
}

Status Pop(LinkStack& S, SElemType& e)
{
	if (S->next == NULL)
		return 0;
	
	//若有一个以上元素
	e = S->next->data;           //将栈顶元素赋给e
	LinkStack ptmp = S->next->next;//用临时变量保存栈顶元素空间以备释放
	free(S->next);
	S->next = ptmp;             //栈顶指针
	//printf("删除栈顶的元素:"); visit(e);
	return 1;
}

Status visit(SElemType e)
{
	printf(" %c\n", e);
	return 1;
}

//操作结果,从栈底到栈顶 依次对栈中每个数据元素调用函数visit(),一旦visit()失败,则操作失败
Status StackTraverse(LinkStack S, Status(*visit)(SElemType))
{
	if (S->next == NULL)
	{
		printf("栈为空!\n");
		return 0;
	}
	for (int i = StackLength(S); i > 0; i--)
	{
		LinkStack p = S->next;    //p指向栈顶
		int  j = 1;
		while (p && j < i)        //顺指针向后查找,直到p指向第i个元素或p为空
		{
			p = p->next;
			++j;
		}
		visit(p->data);
	}
	printf("\n");
	return 1;
}


//操作结果,从栈顶到栈底依次对栈中每个数据元素调用函数visit(),一旦visit()失败,则操作失败
Status StackTraverse_Top(LinkStack S, Status(*pfn_visit)(SElemType))
{
	if (S->next == NULL)
	{
		printf("栈为空!\n");
		return 0;
	}
	LinkStack p = S->next;        //p指向栈顶
	while (p)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
	return 1;
}

//算法部分
//判断运算符栈的(栈顶运算符)与(读入的运算符)之间的优先关系
SElemType Precede(SElemType t1, SElemType t2)
{
	SElemType t;
	switch(t1)
	{
	case'+':
	case'-':
		if (t2 == '*' || t2 == '/' || t2 == '(')
			t = '<';
		else
			t = '>';
		break;
	
	case '*':
	case'/':
		if (t2 == '(')
			t = '<';
		else
			t = '>';
		break;
	
	case'(':
		if (t2 == ')')
			t = '=';
		else if (t2 == '#')
			return 0;
		else t = '<';
		break;
	
	case')':
		if (t2 == '(')
			return 0;
		else t = '>';
		break;

	case'#':
		if (t2 == ')')
			return 0;
		else if (t2 == '#')
			t = '=';
		else t = '<';
		break;
	}
	return t;
}

//进行二元运算 
SElemType Operator(SElemType a, SElemType theta, SElemType b)
{
	SElemType ret;
	switch (theta)
	{
	case '+':
		ret = (a - 48) + (b - 48) + 48;
		break;
	case '-':
		ret = (a - 48) - (b - 48) + 48;
		break;
	case '*':
		ret = (a - 48) * (b - 48) + 48;
		break;
	case '/':
		ret = (a - 48) / (b - 48) + 48;
		break;
	}
	return ret;
}


Status In(SElemType c) //判定读入的字符ch是否为运算符
{
	switch (c)
	{
	case'+':
	case'-':
	case'*':
	case'/':
	case'(':
	case')':
	case'#':
	case'=':
		return 1;
		break;
	default:
		return 0;
	}
}

//算法3.4 
OperandType ExvaluateExpression()
{
	LinkStack OPTR;  //运算符栈:寄存运算符
	LinkStack OPND;  //运算数栈:寄存操作数或运算结果
	char c, x, theta, a, b, e;

	InitStack(OPTR);
	InitStack(OPND);
	Push(OPTR, '#');                //表达式起始符#为运算符栈的栈底元素

	printf("输入表达式:\n");
	c = getchar();
	GetTop(OPTR, e);

	while (c != '#' || e != '#')   //当前读入的字符 或 运算符栈顶元素不为#
	{
		if (!In(c))//不是运算符(操作数或结果)则进OPND栈
		{
			Push(OPND, c);
			c = getchar();
		}
		else      //是运算符,则和运算符栈顶的运算符比较优先级
		{
			GetTop(OPTR, e);
			switch (Precede(e, c))  //比较OPTR的栈底元素和ch的优先级
			{
			case'<':
				Push(OPTR, c);      //当前字符ch压入OPTR栈,读入下一个字符ch
				c = getchar();
				break;
			case'=':               //OPTR栈顶元素是( 而且ch是 )
				Pop(OPTR, x);      //弹出OPTR栈顶的是(,读入下一字符ch
				c = getchar();
				break;
			case'>':
				Pop(OPTR, theta);  //弹出OPTR栈顶的运算符
				Pop(OPND, b);      //弹出OPND栈顶的两个运算数
				Pop(OPND, a);
				Push(OPND, Operator(a, theta, b));//将运算结果压入OPND栈
				break;
			}
		}
		GetTop(OPTR, e);
	}
	GetTop(OPND, e);
	return e;
}

int main()
{
	char c;
	do {
		fflush(stdin);  //清空缓冲区
		c = ExvaluateExpression();
		printf("表达式的值:");
		printf("%d\n", c - 48);
		printf("是否继续(y/n):");
	} while (scanf_s("%s", &c) != 0 && (c == 'y' || c == 'Y'));
	return 0;
}

5.算法3.4舞伴问题

6.算法3.5汉诺塔问题

int c = 0;
void move(char x, int n, char z)
{
	cout << ++c << ".Move disk" << n << "from" << x << "to" << z << "." << endl;
}

void hanoi(int n, char x, char y, char z)
{
	if (n == 1)
		move(x, 1, z);          //将编号为以一的圆盘从x开始移动到z
	else
	{
		hanoi(n - 1, x, z, y);
		move(x, n, z);         //将编号为n的圆盘从x移动到z
		hanoi(n - 1, y, x, z); //将y上编号为1到n-1的圆盘移动到z,x作辅助塔
	}
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-15 11:29:21  更:2022-05-15 11:29:54 
 
开发: 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年5日历 -2024/5/11 2:12:30-

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