堆栈(Stack)是一种特殊的线性表,是一种操作只允许在尾端进行插入或删除等操作的线性表。表尾允许进行插入删除操作,称为栈顶(Top),另一端是固定的,称为栈底(Bottom).栈的操作使按照先进后出或后进先出的原则进行的。

用一片连续的存储空间来存储栈中的数据元素,称为顺序栈(Sequence Stack)。类似于顺序表,用一维数组来存放栈中的数据元素。缺点:浪费存储空间。

用链式存储结构来存储的栈为链栈(Linked Stack).链栈通常用单链表来表示。

Stack

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DataStructure
{ interface IStack<T>
{
void Push(T item); //入栈操作
T Pop(); //出栈操作
T GetTop(); //取栈顶元素
int GetLength(); //求栈的长度
bool IsEmpty(); //判断栈是否为空
void Clear(); //清空操作
}
/// <summary>
/// 顺序栈
/// </summary>
/// <typeparam name="T"></typeparam>
class SequenceStack<T> : IStack<T>
{
private int maxsize; //顺序栈的容量
private T[] data; //数组,用于存储顺序栈中的数据元素
private int top; //指示顺序栈的栈顶 //索引器
public T this[int index]
{
get { return data[index]; }
set { data[index] = value; }
} //容量属性
public int Maxsize
{
get { return maxsize; }
set { maxsize = value; }
} //栈顶属性
public int Top
{
get
{
return top;
}
} public SequenceStack(int size)
{
data = new T[size];
maxsize = size;
top = -;
} //求栈的长度
public int GetLength()
{
return top + ;
}
//清空顺序栈
public void Clear()
{
top = -;
}
//判断顺序栈是否为空
public bool IsEmpty()
{
if (top == -)
{
return true;
}
else
return false;
}
//判断栈是否为满
public bool IsFull()
{
if (top == maxsize - )
{
return true;
}
else
return false;
} //入栈
public void Push(T elem)
{
if (IsFull())
{
Console.WriteLine("Stack is Full !");
return;
}
data[++top] = elem; } //出栈
public T Pop()
{
T tem = default(T);
if (IsEmpty())
{
Console.WriteLine("Stack is Empty !");
return default(T);
}
tem = data[top];
--top;
return tem;
} //获取栈顶元素
public T GetTop()
{
if (IsEmpty())
{
Console.WriteLine("Stack is Empty !");
return default(T);
}
return data[top];
} } /// <summary>
/// 用顺序栈解决火车车厢重排问题
/// </summary>
class TrainArrangwBySeqStack
{
//车厢重排算法,K个缓冲铁轨,车厢初始排序存放在P中
public bool RailRoad(int[] p, int n, int k)
{
//创建与缓冲铁轨对应的堆栈
SequenceStack<int>[] H;
H = new SequenceStack<int>[k + ];
for (int i = ; i <= k; i++)
H[i] = new SequenceStack<int>(p.Length);
int NowOut = ; //下次要输出的车厢
int minH = n + ; //缓冲铁轨中编号最小的车厢
int minS = ; //minH号车厢对应的缓冲铁轨 //车厢重排
for (int i = ; i < n; i++)
{
if (p[i] == NowOut)
{
Console.WriteLine("Move car {0} from input to output", p[i]);
NowOut++;
//从缓冲铁轨中输出
while (minH == NowOut)
{
Output(ref minH, ref minS, ref H, k, n);
NowOut++;
}
}
else
{
if (!Hold(p[i], ref minH, ref minS, ref H, k, n))
{
return false;
}
}
}
return true;
} //在一个缓冲区中放入车厢C
public bool Hold(int c, ref int minH, ref int minS, ref SequenceStack<int>[] H, int k, int n)
{
//如果没有可用的缓冲铁轨,则返回false
//否则返回true
//为车厢c寻找最优的铁轨
//初始化 int BestTrack = ; //目前最优的铁轨
int BestTop = n + ; //最优铁轨上的头辆车厢
int x; //车厢索引 //扫描缓冲铁轨
for (int i = ; i <= k; i++)//!!!i=1
{
if (!H[i].IsEmpty())
{
//铁轨i不为空
x = H[i][H[i].Top];
if (c < x && x < BestTop)
{
//铁轨i顶部的车厢编号最小
BestTop = x;
BestTrack = i;
}
}
else//铁轨i为空
{
if (BestTrack == )
{
BestTrack = i;
}
break;
}
}
if (BestTrack == )
return false;//没有可用铁轨 //把车厢c送入缓冲铁轨
H[BestTrack].Push(c);
Console.WriteLine("Move car{0} from input to holding track {1}", c, BestTrack);
//必要时修改minH minS
if (c < minH)
{
minH = c;
minS = BestTrack;
}
return true;
} //把车厢从缓冲区铁轨送至出轨处,同时修改minH minS
public void Output(ref int minH, ref int minS, ref SequenceStack<int>[] H, int k, int n)
{
int c;//车厢索引
//从堆栈minS中删除编写、好最小的车厢minH
c = H[minS].Pop();
Console.WriteLine("Move car{0} from holding track {1} to output", minH, minS);
//通过检查所有的栈顶,搜索新的minH minS
minH = n + ;
for (int i = ; i <= k; i++)
{
if (!H[i].IsEmpty() && (c = H[i][H[i].Top]) < minH)
{
minH = c;
minS = i;
}
}
}
} /// <summary>
/// 链栈结点
/// </summary>
class StackNode<T>
{
private T data; //数据域
private StackNode<T> next; //引用域 public StackNode()
{
data = default(T);
next = null;
} public StackNode(T val)
{
data = val;
next = null;
} public StackNode(T val, StackNode<T> p)
{
data = val;
next = p;
} //数据域属性
public T Data
{
get { return data; }
set { data = value; }
} //引用域属性
public StackNode<T> Next
{
get { return next; }
set { next = value; }
} } /// <summary>
/// 链栈
/// </summary>
/// <typeparam name="T"></typeparam>
class LinkStack<T> : IStack<T>
{
private StackNode<T> top; //栈顶指示器
private int size; //栈中元素的个数 //栈顶指示器属性
public StackNode<T> Top
{
get { return top; }
set { top = value; }
} //元素个数属性
public int Size
{
get { return size; }
set { size = value; }
} public LinkStack()
{
top = null;
size = ;
} //判断链栈是否为空
public bool IsEmpty()
{
if ((top == null) && (size == ))
return true;
else
return false;
} public int GetLength()
{
return size;
} public void Clear()
{
top = null;
size = ;
} //入栈操作
//在单链表的起始处插入一个结点
public void Push(T item)
{
StackNode<T> q = new StackNode<T>(item);
if (top == null)
{
top = q;
}
else
{
//将新结点的next指向栈顶指示器top所指向的结点
q.Next = top;
//将栈顶指示器top指向新结点
top = q;
}
++size;
} //出栈操作
public T Pop()
{
if (IsEmpty())
{
Console.WriteLine("Stack is empty !");
return default(T);
}
StackNode<T> p = top;
top = top.Next;
--size;
return p.Data;
} //获取栈顶结点的值
public T GetTop()
{
if (IsEmpty())
{
Console.WriteLine("Stack is empty !");
return default(T);
}
return top.Data;
}
} /// <summary>
/// 用链栈解决火车车厢重排问题
/// </summary>
class TrainArrangeByLinkStack
{
//k个缓冲铁轨,车厢初始排序存储在p中
public bool RailRoad(int[] p, int n, int k)
{
//创建与缓冲铁轨对应的堆栈
LinkStack<int>[] H;
H = new LinkStack<int>[k + ];
for (int i = ; i <= k; i++)
{
H[i] = new LinkStack<int>();
} int NowOut = ; //下一次要输出的车厢
int minH = n + ; //缓冲铁轨中编号最小的车厢
int minS = ; //minH号车厢对应的缓冲铁轨 //车厢重排
for (int i = ; i < n; i++)
{
if (p[i] == NowOut)
{
Console.WriteLine("Move car {0} from input to output", p[i]);
NowOut++; //从缓冲铁轨中输出
while (minH == NowOut)
{
Output(ref minH, ref minS, ref H, k, n);
NowOut++;
}
}
else
{
//将p[i]送入缓冲铁轨
if (!Hold(p[i], ref minH, ref minS, ref H, k, n))
return false;
}
}
return true;
} //在一个缓冲铁轨中放入车厢c
public bool Hold(int c, ref int minH, ref int minS, ref LinkStack<int>[] H, int k, int n)
{
//如果没有可用缓冲铁轨,则返回false
//否则返回true
//为车厢c寻找最优的缓冲铁轨
//初始化
int BestTrack = ; //目前最优的铁轨
int BestTop = n + ; //最优铁轨上的头辆车厢
int x; //车厢索引 //扫描缓冲铁轨
for (int i = ; i <= k; i++)
{
if (!H[i].IsEmpty())
{
//铁轨不为空
x = H[i].Top.Data;
if (c < x && x < BestTop)
{
BestTop = x;
BestTrack = i;
}
}
else
{
if (BestTrack == )
BestTrack = i;
break;
}
}
if (BestTrack == )
return false;//没有可用铁轨
//把车厢c送入缓冲铁轨
H[BestTrack].Push(c);
Console.WriteLine("Move car {0} from input to holding track {1}", c, BestTrack); if (c < minH)
{
minH = c;
minS = BestTrack;
}
return true;
} //把车厢从缓冲铁轨送至出轨处,同时修改minH minS
public void Output(ref int minH,ref int minS ,ref LinkStack <int>[] H,int k,int n)
{
int c; //车厢索引
c = H[minS].Pop();
Console.WriteLine("Move car {0} form holding track {1} to output", minH, minS);
//通过检查所有的栈顶,搜索新的minH和minS
minH = n + ;
for (int i = ; i <= k; i++)
{
if (!H[i].IsEmpty() && (c = H[i].Top.Data) < minH)
{
minH = c;
minS = i;
}
}
}
} class Stack
{ static void Main()
{
int[] p = new int[] { , , , , , , , , };
int k = ; //用顺序栈解决火车车厢重排问题
TrainArrangwBySeqStack tas = new TrainArrangwBySeqStack();
bool results;
results = tas.RailRoad(p, p.Length, k);
do
{
if (results == false)
{
Console.WriteLine("need more holding track, please enter additional number:");
k = k + Convert.ToInt32(Console.ReadLine());
results = tas.RailRoad(p, p.Length, k);
}
} while (results == false);
Console.ReadLine(); //用链栈解决火车车厢重排问题
TrainArrangeByLinkStack ta = new TrainArrangeByLinkStack();
bool result;
result = ta.RailRoad(p, p.Length, k);
do
{
if (result == false)
{
Console.WriteLine("need more holding track,please enter additional number:");
k = k + Convert.ToInt32(Console.ReadLine());
result = ta.RailRoad(p, p.Length, k);
}
} while (result == false);
Console.ReadLine();
}
}
}

C#实现堆栈的更多相关文章

  1. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  2. History API与浏览器历史堆栈管理

    移动端开发在某些场景中有着特殊需求,如为了提高用户体验和加快响应速度,常常在部分工程采用SPA架构.传统的单页应用基于url的hash值进行路由,这种实现不存在兼容性问题,但是缺点也有--针对不支持o ...

  3. JVM学习(2)——技术文章里常说的堆,栈,堆栈到底是什么,从os的角度总结

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 堆栈是栈 JVM栈和本地方法栈划分 Java中的堆,栈和c/c++中的堆,栈 数据结构层面的堆,栈 os层面 ...

  4. arcgis engine 中出现的内存堆栈溢出问题。

    两种解决方案: 1.循环加载mxd文档的时候出现的堆栈溢出,解决办法是每次循环结束时清空FeatureLayer,感觉并不好,但是确实可以实现功能. 2.循环调取featureclass的search ...

  5. java 堆栈 理解

    Java 中的堆和栈 堆和栈:分为数据结构的堆和栈以及内存中的堆和栈,两种理解应区分开. 数据结构中的堆: 堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权. 堆性质: ...

  6. python列表模拟堆栈和队列

    对列特点:先进先出.后进后出 用列表insert.pop模拟进队出队: >>> l = [] >>> l.insert(0,'p1') >>> l ...

  7. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  8. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  9. C和指针 第十七章 经典数据类型 堆栈 队列 二叉树

    堆栈: // // Created by mao on 16-9-16. // #ifndef UNTITLED_STACK_H #define UNTITLED_STACK_H #define TR ...

  10. gdb调试汇编堆栈过程的学习

    gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...

随机推荐

  1. android 5.0以下版本使用atof报错解决

    经过测试,如果手机系统在5.0之下,项目project.properties的target若在5.0以上(android-20), NDK 使用atof就会报错: cannot locate symb ...

  2. CentOS 6.5 升级 GCC 4.9.3

    1. GUN官网下载源代码安装包: gcc-4.9.3.tar.gz 2. 解压安装包,并进入解压后的文件夹: tar -zxvf gcc-4.9.3.tar.gz 3. 使用压缩包中的工具下载依赖: ...

  3. const成员变量初始化总结

    const可以用来声明常量也就是说他的值不能被修改: const成员必须在定义的时候同时初始化,不能进行赋值 如 const int a:a的值不能修改,不能给它赋值,如何才能让它一开始就拥有一个值? ...

  4. Call me evilxr

    我是Evilxr,博客新开第一天:希望自己能坚持下去!之前友友推荐的是oschina,使用了一段时间发现oschina经常抽风,再者自己平时也有关注一些博客觉得cnblogs也不错,开博的初衷是想记录 ...

  5. Android 中 非对称(RSA)加密和对称(AES)加密

    在非对称加密中使用的主要算法有:RSA.Elgamal.背包算法.Rabin.D-H.ECC(椭圆曲线加密算法)等. 优点: 非对称加密与对称加密相比,其安全性更好:对称加密的通信双方使用相同的秘钥, ...

  6. js内存泄露的几种情况

    想解决内存泄露问题,必须知道什么是内存泄露,什么情况下出现内存泄露,才能在遇到问题时,逐个排除.这里只讨论那些不经意间的内存泄露. 一.什么是内存泄露 内存泄露是指一块被分配的内存既不能使用,又不能回 ...

  7. SQL NOT EXISTS

    看了一篇文章,虽然知识点很简单,但是还是帮我理解了一些以前没想到的东西 一共三个表student,class,score create table student(sno varchar(50) no ...

  8. Vim的分割窗口split命令

    显示两个不同的文件:或者同时显示一个文件的两个不同地方:又或者并排比较两个文件.这一切都可以通过分割窗口实现. 打开新窗口最简单的命令如下: :split (水平分割) || :vsplit (垂直分 ...

  9. Mysql(一)

    一.Mysql简介 Mysql是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle旗下.特点:其体积小.速度快.开源. 分为社区办和商业版,其社区版性能卓越. 二.Ubun ...

  10. CommittableTransaction和TransactionScope

    创建可提交事务 下面的示例创建一个新的 CommittableTransaction 并提交它. //Create a committable transaction tx = new Committ ...