博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构——栈
阅读量:6427 次
发布时间:2019-06-23

本文共 7692 字,大约阅读时间需要 25 分钟。

1 栈具有后进先出(LIFO)的操作特点,是操作受限的线性表。栈的存储有顺序栈和链栈两种。

2 在顺序存储方式下,采用一维数组(即向量)来模拟连续的存储空间。通常将0下表作为栈底,栈的第一个元素(即栈底元素)存放在0下表位置。顺序栈的实现:

//SqStack.h#ifndef _SQSTACK_#define _SQSTACK_template
class SqStack{public: SqStack(int); ~SqStack(); void Clear(); bool Empty() const; int Length() const; T& Top() const; void Push(const T&); void Pop();private: T* m_base; int m_top; int m_size;};template
SqStack
::SqStack(int m){ m_top = 0; m_base = new T[m]; m_size = m;}template
SqStack
::~SqStack(){ if (m_base != NULL) delete [] m_base;}template
void SqStack
::Clear(){ m_top = 0;}template
bool SqStack
::Empty() const{ return m_top == 0;}template
int SqStack
::Length() const{ return m_top;}template
T& SqStack
::Top() const{ if (m_top != 0) { return m_base[m_top-1]; }}template
void SqStack
::Push(const T& e){ if (m_top >= m_size) { T* newbase = new T[m_size+10]; for (int i = 0; i < m_size; i++) { newbase[i] = m_base[i]; } delete [] m_base; m_base = newbase; m_size += 10; } m_base[m_top++] = e;}template
void SqStack
::Pop(){ m_top--;}#endif
3 用链式存储结构实现的栈成为链栈。当栈非空时,top指向栈顶元素结点;而当栈为空时,top为空指针。链栈的实现:
//LinkStack.h#ifndef _LINKSTACK_#define _LINKSTACK_template
struct LinkNode{ T data; LinkNode
* next;};template
class LinkStack{public: LinkStack(); ~LinkStack(); void Clear(); int Length() const; bool Empty() const; T& Top() const; void Push(const T&); void Pop();private: LinkNode
*top;};template
LinkStack
::LinkStack(){ top = NULL;}template
LinkStack
::~LinkStack(){ Clear();}template
void LinkStack
::Clear(){ LinkNode
* p; while(top) { p = top; top = top->next; delete p; }}template
bool LinkStack
::Empty() const{ return top == NULL;}template
int LinkStack
::Length() const{ LinkNode
* p = top; int i = 0; while (p) { i++; p = p->next; } return i;}template
T& LinkStack
::Top() const{ if (top) { return top->data; }}template
void LinkStack
::Push(const T& e){ LinkNode
* p = new LinkNode
; p->data = e; p->next = top; top = p;}template
void LinkStack
::Pop(){ LinkNode
* p = top; top = top->next; delete p;}#endif
4 栈的应用

4.1 回文判断。

所谓回文,是指一个字符串的字符序列(不包括空格)顺读和逆读是一样的。例如“dad”,"noon"都是回文。程序实现如下:

#include 
#include "SqStack.h"#include "LinkStack.h"using namespace std;#define MAX_STRING_LEN 100bool ispalindrome(char*);void main(int argc, char* argv[]){ char instring[MAX_STRING_LEN]; cin.getline(instring,MAX_STRING_LEN); if (ispalindrome(instring)) { cout<<"YES"<
s(MAX_STRING_LEN); char deblankstring[MAX_STRING_LEN],c; int i = 0; while (*in_string) { if (*in_string != ' ') { deblankstring[i++] = *in_string; } in_string++; } deblankstring[i] = '\0'; i = 0; while (deblankstring[i]) { s.Push(deblankstring[i++]); } int k = 0; while (!s.Empty()) { c = s.Top(); s.Pop(); if (c != deblankstring[k++]) { return false; } } return true;}
4.2 迷宫问题
#include 
#include "SqStack.h"#include
using namespace std;#define MAXSIZE 30struct PosType{ int x; //行 int y; //列};struct DataType{ PosType seat; //位置 int di; //方向};class Maze{public: Maze(int, int); ~Maze(); bool MazePath(PosType, PosType); void Input(); void Print();private: PosType NextPos(PosType, int); int ** m_maze; int m_row; int m_col;};Maze::Maze(int m, int n){ m_row = m + 2; m_col = n + 2; m_maze = new int*[m_row]; for (int i = 0; i < m_row; i++) { m_maze[i] = new int[m_col]; }}Maze::~Maze(){ for (int i = 0; i < m_row; i++) { if (m_maze[i] != NULL) { delete [] m_maze[i]; } } if (m_maze != NULL) { delete [] m_maze; }}bool Maze::MazePath(PosType start, PosType end){ SqStack
path(MAXSIZE); PosType curpos; DataType e; curpos = start; int curstep = 1; do { if (m_maze[curpos.x][curpos.y] == 0) { m_maze[curpos.x][curpos.y] = curstep; e.seat.x = curpos.x; e.seat.y = curpos.y; e.di = 0; path.Push(e); curstep++; if (curpos.x == end.x && curpos.y == end.y) //达到终点 { return true; } curpos = NextPos(curpos, e.di); } else { if (!path.Empty()) { e = path.Top(); path.Pop(); curstep--; while (e.di == 3 && !path.Empty()) { m_maze[e.seat.x][e.seat.y] = -1; //留下不能通过的标记 e = path.Top(); //退回一步 path.Pop(); curstep--; } if (e.di < 3) //没到最后一个方向 { e.di++; //换下一个方向搜索 path.Push(e); curstep++; curpos = NextPos(e.seat,e.di); } } } } while (!path.Empty()); return false;}void Maze::Input(){ int i,j; ifstream input("input.txt"); cout<<"请输入"<
<<"*"<
<<"的迷宫:"<
>m_maze[i][j]; } } for (i = 0; i < m_row; i++) { m_maze[i][0] = 1; m_maze[i][m_col-1] = 1; } for (j = 0; j < m_col; j++) { m_maze[0][j] = 1; m_maze[m_row-1][j] = 1; }}void Maze::Print(){ int i, j; for (i = 0; i < m_row; i++) { for (j = 0; j < m_col; j++) { if (m_maze[i][j] >= 0 && m_maze[i][j] < 10) { cout<<" "<
>m>>n; Maze maze(m,n); maze.Input(); maze.Print(); cout<<"请输入入口位置(行数,列数)"; cin>>begin.x>>begin.y; cout<<"请输入出口位置(行数,列数)"; cin>>end.x>>end.y; bool b = maze.MazePath(begin, end); if (b) { cout<<"此迷宫从入口到出口的一条路径如下:"<
4.3 表达式求值,例如求取表达式“7+(9-12/3)*4=”的值。
#include 
#include "SqStack.h"#include
using namespace std;#define MaxExpLength 100char ops[7] = {'+','-','*','/','(',')','='};char cmp[7][7] = { {'>','>','<','<','<','>','>'}, {'>','>','<','<','<','>','>'}, {'>','>','>','>','<','>','>'}, {'>','>','>','>','<','>','>'}, {'<','<','<','<','<','=',' '}, {'>','>','>','>',' ','>','>'}, {'<','<','<','<','<',' ','='}};//判断ch是否为运算符bool IsOperator(char ch){ for (int i = 0; i < 7; i++) { if (ch == ops[i]) { return true; } } return false;}//比较运算符的优先级char Compare(char ch1, char ch2){ char priority; int m,n; for (int i = 0; i < 7; i++) { if (ch1 == ops[i]) { m = i; } if (ch2 == ops[i]) { n = i; } } priority = cmp[m][n]; return priority;}//计算z=x
y,若除数为0,则返回falsebool Compute(double x, char op, double y, double& z){ switch (op) { case '+': z = x + y; break; case '-': z = x - y; break; case '*': z = x * y; break; case '/': if (y != 0.0) { z = x / y; break; } else { cout<<"除数为0,出错!"<
optr(20); SqStack
opnd(20); optr.Push('='); ch = str[i++]; while (ch != '=' || optr.Top() != '=') { while (ch == ' ') { ch = str[i++]; } if (IsOperator(ch)) //ch是操作符 { switch(Compare(optr.Top(), ch)) { case '<': optr.Push(ch); ch = str[i++]; break; case '=': optr.Pop(); ch = str[i++]; break; case '>': op = optr.Top(); optr.Pop(); b = opnd.Top(); opnd.Pop(); a = opnd.Top(); opnd.Pop(); if (Compute(a,op,b,v)) { opnd.Push(v); break; } else { result = 0; return false; } } } else //ch是数字 { temp = ch - '0'; ch = str[i++]; while (!IsOperator(ch) && ch != ' ') { temp = temp * 10 + ch - '0'; ch = str[i++]; } opnd.Push(temp); } } result = opnd.Top(); return true;}void main(int argc, char* argv[]){ int i = 0; double result; char* str; cout<<"请输入一个正确的四则表达式(以\"=\"结束,运算符为正整数):"<
>str[i]; while (str[i] != '=') { input>>str[++i]; } if (ExpEvaluation(str, result)) { cout<<"表达式的值是"<
<

4.4 汉诺塔问题

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

#include 
#include
using namespace std;int times;//将第n个圆盘从x柱移到z柱void move(int n, char x, char z){ cout<<"第"<<++times<<"步,将"<
<<"号盘从"<
<<"移到"<
<
>n; hanoi(n, 'a', 'b', 'c'); system("pause");}

转载地址:http://aybga.baihongyu.com/

你可能感兴趣的文章
JPA或Hibernate中的
查看>>
web_find和web_reg_find 区别(转载)
查看>>
请设计一个算法能够完成两个用字符串存储的整数进行相加操作,对非法的输入则返回error...
查看>>
开博宣言
查看>>
【目录】 软件测试全栈需要学习什么? 软件测试的各个阶段 ,软件测试学习路径,软件测试方向选择,软件测试的薪资待遇。...
查看>>
CSS3动画【归纳总结】
查看>>
Web应用程序项目 已配置为使用IIS
查看>>
ElasticSearch-倒排索引
查看>>
Algs4-2.1.18可视轨迹-选择排序
查看>>
Algs4-2.2.5自顶向下和自底向上的归并排序的子数组和大小
查看>>
ASP.NET温故而知新学习系列之ASP.NET多线程编程—.NET下的多线程编程Thread中委托的使用(六)...
查看>>
Django完整的登录示例,APP,ORM介绍和使用
查看>>
使用 Spring HATEOAS 开发 REST 服务
查看>>
最新整理知识结构图
查看>>
linux安装mysql
查看>>
flask 2 进阶
查看>>
JS 循环遍历JSON数据
查看>>
0516JS练习:综合2
查看>>
【学时总结】◆学时·VI◆ SPLAY伸展树
查看>>
extjs_1 初识
查看>>