堆栈(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 = -1;}//求栈的长度public int GetLength(){return top + 1;}//清空顺序栈public void Clear(){top = -1;}//判断顺序栈是否为空public bool IsEmpty(){if (top == -1){return true;}elsereturn false;}//判断栈是否为满public bool IsFull(){if (top == maxsize - 1){return true;}elsereturn 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 + 1];for (int i = 0; i <= k; i++)H[i] = new SequenceStack<int>(p.Length);int NowOut = 1;     //下次要输出的车厢int minH = n + 1;   //缓冲铁轨中编号最小的车厢int minS = 0;       //minH号车厢对应的缓冲铁轨//车厢重排for (int i = 0; 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;}//在一个缓冲区中放入车厢Cpublic bool Hold(int c, ref int minH, ref int minS, ref SequenceStack<int>[] H, int k, int n){//如果没有可用的缓冲铁轨,则返回false//否则返回true//为车厢c寻找最优的铁轨//初始化int BestTrack = 0;       //目前最优的铁轨int BestTop = n + 1;     //最优铁轨上的头辆车厢int x;                   //车厢索引//扫描缓冲铁轨for (int i = 1; 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 == 0){BestTrack = i;}break;}}if (BestTrack == 0)return false;//没有可用铁轨//把车厢c送入缓冲铁轨
            H[BestTrack].Push(c);Console.WriteLine("Move car{0} from input to holding track {1}", c, BestTrack);//必要时修改minH minSif (c < minH){minH = c;minS = BestTrack;}return true;}//把车厢从缓冲区铁轨送至出轨处,同时修改minH minSpublic void Output(ref int minH, ref int minS, ref SequenceStack<int>[] H, int k, int n){int c;//车厢索引//从堆栈minS中删除编写、好最小的车厢minHc = H[minS].Pop();Console.WriteLine("Move car{0} from holding track {1} to output", minH, minS);//通过检查所有的栈顶,搜索新的minH minSminH = n + 2;for (int i = 1; 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 = 0;}//判断链栈是否为空public bool IsEmpty(){if ((top == null) && (size == 0))return true;elsereturn false;}public int GetLength(){return size;}public void Clear(){top = null;size = 0;}//入栈操作//在单链表的起始处插入一个结点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 + 1];for (int i = 1; i <= k; i++){H[i] = new LinkStack<int>();}int NowOut = 1;     //下一次要输出的车厢int minH = n + 1;   //缓冲铁轨中编号最小的车厢int minS = 0;       //minH号车厢对应的缓冲铁轨//车厢重排for (int i = 0; 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;}//在一个缓冲铁轨中放入车厢cpublic bool Hold(int c, ref int minH, ref int minS, ref LinkStack<int>[] H, int k, int n){//如果没有可用缓冲铁轨,则返回false//否则返回true//为车厢c寻找最优的缓冲铁轨//初始化int BestTrack = 0;             //目前最优的铁轨int BestTop = n + 1;           //最优铁轨上的头辆车厢int x;                         //车厢索引//扫描缓冲铁轨for (int i = 1; i <= k; i++){if (!H[i].IsEmpty()){//铁轨不为空x = H[i].Top.Data;if (c < x && x < BestTop){BestTop = x;BestTrack = i;}}else{if (BestTrack == 0)BestTrack = i;break;}}if (BestTrack == 0)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 minSpublic 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和minSminH = n + 2;for (int i = 1; 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[] { 3, 6, 9, 2, 4, 7, 1, 8, 5 };int k = 3;//用顺序栈解决火车车厢重排问题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();}}
}

队列(Queue)是插入操作限定在表的尾部而其他操作限定在表的头部进行的线性表。把进行插入操作的表尾称为队尾(Rear).把进行其他操作的头部称为队头(Front).

队列的操作使按照先进先出后进后出的原则进行的。

用一片连续的存储空间来存储队列中的数据元素,称为顺序队列(Sequence Queue)。类似于顺序表,用一维数组来存放队列中的数据元素。

解决顺序队列的假溢出的方法是将顺序队列看成是首位相接的循环结构,叫循环顺序队列(Circular sequence Queue)

队列的另外一种存储方式是链式存储,称为链队列(Linked Queue)。通常用单链表表示。

Queue

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace DataStructure
{/// <summary>/// 队列接口/// </summary>interface IQueue<T>{void EnQueue(T elem);         //入队列操作T DeQueue();                  //出队列操作T GetFront();                 //取对头元素int GetLength();              //求队列的长度bool IsEmpty();               //判断队列是否为空void Clear();                 //清空队列bool IsFull();                //判断队列是否为满
    }/// <summary>/// 银行队列接口/// </summary>interface IBankQueue : IQueue<int>{int GetCallnumber();          //获取服务号码
    }/// <summary>/// 循环顺序队列/// </summary>/// <typeparam name="T"></typeparam>class CSeqQueue<T> : IQueue<T>{private int maxsize;       //循环顺序队列的容量private T[] data;          //数组,用于存储循环顺序队列中的数据元素private int front;         //指示最近一个已经离开队列的元素所占有的位置 循环顺序队列的对头private int rear;          //指示最近一个进入队列的元素的位置           循环顺序队列的队尾public T this[int index]{get { return data[index]; }set { data[index] = value; }}//容量属性public int Maxsize{get { return maxsize; }set { maxsize = value; }}//对头指示器属性public int Front{get { return front; }set { front = value; }}//队尾指示器属性public int Rear{get { return rear; }set { rear = value; }}public CSeqQueue(){}public CSeqQueue(int size){data = new T[size];maxsize = size;front = rear = -1;}//判断循环顺序队列是否为满public bool IsFull(){if ((front == -1 && rear == maxsize - 1) || (rear + 1) % maxsize == front)return true;elsereturn false;}//清空循环顺序列表public void Clear(){front = rear = -1;}//判断循环顺序队列是否为空public bool IsEmpty(){if (front == rear)return true;elsereturn false;}//入队操作public void EnQueue(T elem){if (IsFull()){Console.WriteLine("Queue is Full !");return;}rear = (rear + 1) % maxsize;data[rear] = elem;}//出队操作public T DeQueue(){if (IsEmpty()){Console.WriteLine("Queue is Empty !");return default(T);}front = (front + 1) % maxsize;return data[front];}//获取对头数据元素public T GetFront(){if (IsEmpty()){Console.WriteLine("Queue is Empty !");return default(T);}return data[(front + 1) % maxsize];//front从-1开始
        }//求循环顺序队列的长度public int GetLength(){return (rear - front + maxsize) % maxsize;}}/// <summary>/// 链队列结点类/// </summary>/// <typeparam name="T"></typeparam>class QueueNode<T>{private T data;                   //数据域private QueueNode<T> next;        //引用域public QueueNode(T val, QueueNode<T> p){data = val;next = p;}public QueueNode(QueueNode<T> p){next = p;}public QueueNode(T val){data = val;next = null;}public QueueNode(){data = default(T);next = null;}//数据域属性public T Data{get { return data; }set { data = value; }}//引用域属性public QueueNode<T> Next{get { return next; }set { next = value; }}}/// <summary>/// 链队列类/// </summary>/// <typeparam name="T"></typeparam>class LinkQueue<T> : IQueue<T>{private QueueNode<T> front;    //队列头指示器private QueueNode<T> rear;     //队列尾指示器private int size;              //队列结点个数//队列属性public QueueNode<T> Front{get { return front; }set { front = value; }}public QueueNode<T> Rear{get { return rear; }set { rear = value; }}public int Size{get { return size; }set { size = value; }}//初始化链队列public LinkQueue(){front = rear = null;size = 0;}public int GetLength(){return size;}public void Clear(){front = rear = null;size = 0;}public bool IsEmpty(){if ((front == rear) && (size == 0))return true;elsereturn false;}//链队列没有容量限制 返回falsepublic bool IsFull(){return false;}//入队操作public void EnQueue(T item){QueueNode<T> q = new QueueNode<T>(item);if (IsEmpty()){front = q;rear = q;}else{rear.Next = q;rear = q;}++size;}//出对操作public T DeQueue(){if (IsEmpty()){Console.WriteLine("Queue is Empty !");return default(T);}QueueNode<T> p = front;front = front.Next;if (front == null){rear = null;}--size;return p.Data;}//获取链队列头结点的值public T GetFront(){if (IsEmpty()){Console.WriteLine("Queue is Empty !");return default(T);}return front.Data;}}/// <summary>/// 银行叫号链队列类/// </summary>class LinkBankQueue : LinkQueue<int>, IBankQueue{private int callnumber;public int Callnumber{get { return callnumber; }set { callnumber = value; }}//获取服务号码public int GetCallnumber(){if ((IsEmpty()) && callnumber == 0){callnumber = 1;}elsecallnumber++;return callnumber;}}/// <summary>/// 银行叫号顺序队列类/// </summary>class CSeqBankQueue : CSeqQueue<int>, IBankQueue{private int callnumber;  //记录系统自动产生的新来顾客的服务号码public int Callnumber{get { return callnumber; }set { callnumber = value; }}public CSeqBankQueue(){}public CSeqBankQueue(int size): base(size){}//获得服务号码public int GetCallnumber(){if ((IsEmpty()) && callnumber == 0){callnumber = 1;}else{callnumber++;}return callnumber;}}/// <summary>/// 服务窗口类/// </summary>class ServiceWindow{IBankQueue bankQ;//服务队列属性public IBankQueue BankQ{get { return bankQ; }set { bankQ = value; }}public void Service(){while (true){Thread.Sleep(10000);if (!bankQ.IsEmpty()){Console.WriteLine();lock (bankQ){Console.WriteLine("请{0}号到{1}号窗口!", bankQ.DeQueue(), Thread.CurrentThread.Name);}}}}}class Queue{static void Main(){IBankQueue bankQueue = null;Console.WriteLine("请选择存储结构的类型:1.顺序队列 2.链队列:");char selectFlag = Convert.ToChar(Console.ReadLine());switch (selectFlag){/*初始化顺序队列*/case '1':int count;             //接受循环顺序队列的容量Console.WriteLine("请输入队列可容纳的人数:");count = Convert.ToInt32(Console.ReadLine());bankQueue = new CSeqBankQueue(count);break;/*初始化链队列*/case '2':bankQueue = new LinkBankQueue();break;}int windowcount = 4;       //设置银行柜台的服务窗口数
ServiceWindow[] sw = new ServiceWindow[windowcount];Thread[] swt = new Thread[windowcount];for (int i = 0; i < windowcount; i++){sw[i] = new ServiceWindow();sw[i].BankQ = bankQueue;swt[i] = new Thread(new ThreadStart(sw[i].Service));swt[i].Name = "" + (i + 1);swt[i].Start();}while (true){Console.WriteLine("请点击触摸屏获取号码:");Console.ReadLine();int callnumber;if (!bankQueue.IsFull()){callnumber = bankQueue.GetCallnumber();Console.WriteLine("您的号码是:{0},您前面有{1}位,请等待!", callnumber, bankQueue.GetLength());bankQueue.EnQueue(callnumber);}elseConsole.WriteLine("现在业务繁忙,请稍后再来!");Console.WriteLine();}}}
}

注:本文整理自《数据结构(C#语言版)》 清华大学出版社!!!

复制搜索
复制搜索
复制搜索
复制搜索

转载于:https://www.cnblogs.com/YuanSong/archive/2012/08/20/2648115.html

C# 数据结构 之 堆栈和队列相关推荐

  1. 数据结构之堆栈与队列

    堆栈与队列是两种重要的基础数据结构,一个是先入后出,一个是先入先出,有着广泛的应用,本文分别使用数组与链表实现堆栈与队列 顺序存储方式实现堆栈 #define MaxSize 20 #define E ...

  2. python堆栈与队列_python语言的堆栈与队列类的实现

    基于python语言的数据结构之堆栈与队列的实现 # 堆栈的实现 # -*- coding: utf-8 -*- """ 栈(stack), 是一种容器,可以存入数据元素 ...

  3. Java LinkedList特有方法程序小解 使用LinkedList 模拟一个堆栈或者队列数据结构。...

    package Collection;import java.util.LinkedList;/* LinkedList:特有的方法 addFirst()/addLast(); getFirst()/ ...

  4. 使用LinkedList模拟一个堆栈或者队列数据结构

    使用LinkedList模拟一个堆栈或者队列数据结构. 堆栈:先进后出  如同一个杯子. 队列:先进先出  如同一个水管. import java.util.LinkedList;public cla ...

  5. 数据结构与算法--4.使用堆栈模拟队列

    问题: 队列的插入和删除遵循先入先出的原则,而堆栈遵循后进先出的原则. 用两个堆栈模拟队列,要求实现时不能分配超过O(1)的内存,时间复杂度必须是o(m). 思路: 用两个堆栈模拟队列,必须要支持两种 ...

  6. 《数据结构与算法基础 严蔚敏版》第三章 堆栈与队列

    链接:https://pan.baidu.com/s/1z-kFKiNaezO0k2BWQ8l1Hw  提取码:asdf 1.堆栈 (1)堆栈的概念 栈:只允许在一段进行插入或删除操作的线性表 栈顶: ...

  7. 如何在JavaScript中实现堆栈和队列?

    本文翻译自:How do you implement a Stack and a Queue in JavaScript? What is the best way to implement a St ...

  8. JavaScript学习笔记之 数组方法一 堆栈 和队列

    数组的方法 以及 堆栈的操作的方法 JavaScript是一种弱类型语言,不像其它程序语言需要严格定义数据类型.在JavaScript中数组可以任意修改变动,这样也就出现了一个问题,如果边遍历数组边操 ...

  9. 实验一 线性表、堆栈和队列的操作与实现

    前言 记录实验,同时也是记录常见数据结构算法的实现. 广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A) 学院 计算机科学与网络工程学院 实验课程 数据结构实验 实验项目 实验一 ...

最新文章

  1. the job was canceled什么意思_这些英语短语,因为相差一个“the”导致意思大不相同!...
  2. 如何禁止SAP Fiorigateway系统上的病毒扫描
  3. 32为Linux安卓AVD启动报错
  4. 有人做linux源码注释嘛,linux内核工作队列讲解和源码详细注释
  5. 与成都的幸福行动家交流GTD
  6. 电子信息系统机房设计规范
  7. 爱康科技压力大:前三季亏损1.2亿,中泰证券喊话全年净利3.92亿
  8. php header 生成pdf,使用PHP生成PDF文档
  9. 推荐一款智能黑科技微信小程序,简直不要太良心!
  10. 2022长三角产业区块链生态图谱 附下载
  11. CAD中如何绘制带有箭头的引出标注?
  12. EF Core 5.0原生sql语句执行
  13. 港科夜闻|香港科大(广州)(筹)与民心港人子弟学校签署合作框架协议
  14. 周鸿袆眼里的程序员创业
  15. Graalvm安装配置与springboot3.0尝鲜
  16. 基于白名单的Payload
  17. CRM客户关系管理系统1登录模块分析和退出登录
  18. 物联网工程专业的迷茫与抉择
  19. Android中复制到剪切板
  20. 大学普通班是啥意思?党员信息登记 学历代码 大学普通班是啥

热门文章

  1. 二维数组 赋值_3.9数组(数组基本使用、数组的循环、数组拷贝、数组排序、多维数组)...
  2. 怎么让电脑不自动休眠_【平安惠阳提醒您】电脑应设置自动休眠 避免产生火灾隐患...
  3. 两个多精度十进制数加法程序设计_初中数学之有理数的加减,学会加法,减法即会,掌握技巧轻松计算...
  4. ENSP如何开启服务器的http_如何使用HTTP模块在Node.js中创建Web服务器(上)
  5. 新疆大学OJ(ACM) 1047: string 字符串排序
  6. 诺依曼体系结构、哈佛体系结构与改进型哈佛结构之间的区别
  7. CF-1249 F.Maximum Weight Subset(贪心)
  8. 实现strstr库函数功能
  9. C++容器的选择和详细操作方法总结(有自己总结)
  10. 在多个的共享ndk项目之间共享模块