数据结构中的棧在C#中的实现

一、大致学习

棧是一种面向表的数据结构,棧中的数据只能在标的某一短进行添加和删除操作,是一种典型的(LIFO)数据结构。

现实生活中的理解:自助餐厅的盘子堆,人们总是从顶部取走盘子,当洗碗工把洗好的盘子放回盘子堆的时候也是放在盘子堆的顶部。

Stack类实现棧:Stack<T> number=new Stack<T>();

Stack类是ICollection接口的一个实现(foreach),它代表了一个LIFO群集或一个棧,在.NET中作为循环缓冲来实现的,这使得能动态地分配进栈数据项的空间;

Stack构造器方法,默认的构造器实例化的是一个具有10个数值初始容量的空栈,每当棧达到满容量时就会把容量值翻倍;另一种构造器允许创建一个来自另一个群集对象的棧对象

如:

  1. string [] names= new string[]{"jack","rose","jeff"};
  2.  
  3. Stack nameStack=new Stack(names);

二、具体分析

C#Stack泛型类的常用方法介绍:

1、Push(object item)方法:将对象插入栈顶,同时将棧的初始变量+1

  1. public void Push(object item)
  2. {
  3. list.Add(item);
  4. p_index++;
  5. }

2、Pop()方法:将对象移除栈顶,同时将棧的初始变量-1,返回出棧的对象

  1. public object Pop()
  2. {
  3. object obj=list[p_index];
  4. list.RemoveAt(p_index);
  5. p_index--;
  6. return obj;
  7. }

3、Peek()方法:取数,只是查看栈顶元素的”值“

  1. public object Peek()
  2. {
  3. return list[p_index];
  4. }

4、Clear()方法:清空棧内数据,将数据项计数器设置为0

  1. public void Clear()
  2. {
  3. list.Clear();
  4. p_index = -1;
  5. }

5、Contains()方法:用来确定指定的元素是否在棧内 bool

  1. public bool Contains(object item)
  2. {
  3. return list.Contains(item);
  4. }

6、CopyTo()方法:将棧内的内容复制到一个数组中,要求数组必须是object类型的,因为这是所有棧对象的数据类型。包含两个参数:一个数组和起始索引值

  1. Stack myStack=new Stack();
  2. for(int i=20;i>0;i--)
  3. {
  4. myStack.Push(i);
  5. }
  6. object [] myArray=new object[myStack.Count];
  7. myStack.CopyTo(myArray,0);

7、ToArray()方法:复制到一个新的数组中,不含索引值,故需创建新的数组

  1. Stack myStack=new Stack();
  2. for(int i=0;i>0;i++)
  3. {
  4. myStack.Push(i);
  5. }
  6. object [] myArray=new object[myStack.Count];
  7. myArray=myStack.ToArray();

8、Count属性:获取棧中的元素个数

  1. public int Count
  2. {
  3. get
  4. {
  5. return list.Count;
  6. }
  7. }

三、案例分析

1、使用棧来判断回文

把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。

  1. class CStack
  2. {
  3. private int p_index;
  4. private ArrayList list;
  5. public CStack()
  6. {
  7. list = new ArrayList();
  8. p_index = -1;
  9. }
  10. //获取棧的空间
  11. public int Count
  12. {
  13. get
  14. {
  15. return list.Count;
  16. }
  17. }
  18. //进栈
  19. public void Push(object item)
  20. {
  21. list.Add(item);
  22. p_index++;
  23. }
  24. //出棧
  25. public object Pop()
  26. {
  27. object obj=list[p_index];
  28. list.RemoveAt(p_index);
  29. p_index--;
  30. return obj;
  31. }
  32. //清空棧内元素
  33. public void Clear()
  34. {
  35. list.Clear();
  36. p_index = -1;
  37. }
  38. //取数
  39. public object Peek()
  40. {
  41. return list[p_index];
  42. }
  43. public bool Contains(object item)
  44. {
  45. return list.Contains(item);
  46. }
  47. }
  1. static void Main(string[] args)
  2. {
  3. CStack alist = new CStack();
  4. string ch;
  5. string word = "woainiiniaow";
  6. bool isPalindrome = true;
  7. //将word反转存入棧中
  8. for (int i = 0; i < word.Length;i++ )
  9. {
  10. alist.Push(word.Substring(i,1));
  11. }
  12. //进行判断
  13. int pos = 0;
  14. while(alist.Count>0)
  15. {
  16. ch = alist.Pop().ToString();
  17. if (ch != word.Substring(pos, 1))
  18. {
  19. isPalindrome = false;
  20. break;
  21. }
  22. else
  23. {
  24. pos++;
  25. }
  26. }
  27. if (isPalindrome)
  28. {
  29. Console.WriteLine("{0}是回文", word);
  30. }
  31. else
  32. {
  33. Console.WriteLine("{0}不是回文", word);
  34. }
  35. Console.ReadKey();
  36. } //另外我觉得可采用另一种常规方法就是复制一个“数组”,原“数组”从0->Length遍历,新“数组”从Length->0遍历,进行比对。

2、使用棧来实现四则运算

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Collections;
  7.  
  8. namespace _09使用棧来实现四则运算
  9. {
  10. class Program
  11. {
  12. static void Main(string[] args)
  13. {
  14. Stack nums = new Stack();
  15. Stack ops = new Stack();
  16. string expression = "5*2";
  17. Calculate(nums,ops,expression);
  18. Console.WriteLine(nums.Pop());
  19. Console.ReadKey();
  20. }
  21. /// <summary>
  22. /// 判断是否是数字
  23. /// </summary>
  24. /// <param name="input">要判断参数</param>
  25. /// <returns></returns>
  26. static bool IsNumeric(string input)
  27. {
  28. bool flag = true;
  29. string pattern=(@"^\d+$");
  30. Regex validate = new Regex(pattern);
  31. if(!validate.IsMatch(input))
  32. {
  33. flag = false;
  34. }
  35. return flag;
  36. }
  37. /// <summary>
  38. /// 进栈操作
  39. /// </summary>
  40. /// <param name="N">保存数字的棧</param>
  41. /// <param name="O">保存运算符的棧</param>
  42. /// <param name="exp">运算表达式</param>
  43. static void Calculate(Stack N,Stack O,string exp)
  44. {
  45. string ch, token = "";
  46. for (int i = 0; i < exp.Length;i++ )
  47. {
  48. ch = exp.Substring(i,1);
  49. if (IsNumeric(ch))
  50. {
  51. token = ch;
  52. N.Push(token);
  53. token = "";
  54. }
  55. //if(ch==""||i==(exp.Length-1))
  56. //{
  57. // N.Push(token);
  58. // token = "";
  59. //}
  60. else if(ch=="+"||ch=="-"||ch=="*"||ch=="/")
  61. {
  62. O.Push(ch);
  63. }
  64. if(N.Count==2)
  65. {
  66. Compute(N,O);
  67. }
  68. }
  69.  
  70. }
  71. /// <summary>
  72. /// 进行运算
  73. /// </summary>
  74. /// <param name="N">参与运算的数字的棧</param>
  75. /// <param name="O">参与运算的运算符的棧</param>
  76. static void Compute(Stack N,Stack O)
  77. {
  78. int oper1;
  79. int oper2;
  80. string oper;
  81. oper1 = Convert.ToInt32(N.Pop());
  82. oper2 = Convert.ToInt32(N.Pop());
  83. oper = Convert.ToString(O.Pop());
  84. switch(oper)
  85. {
  86. case"+":
  87. N.Push(oper1+oper2);
  88. break;
  89. case "-":
  90. N.Push(oper1-oper2);
  91. break;
  92. case "*":
  93. N.Push(oper1*oper2);
  94. break;
  95. case "/":
  96. if (oper2 == 0)
  97. {
  98. throw new Exception("除数不能为0");
  99. }
  100. N.Push(oper1/oper2);
  101. break;
  102. }
  103. }
  104. }
  105. }

3、十进制向多种进制进行转换

  1. static void Main(string[] args)
  2. {
  3. int num, baseNum;
  4. Console.Write("Enter a decimal number");
  5. num = Convert.ToInt32(Console.ReadLine());
  6. Console.Write("Enter a base");
  7. baseNum = Convert.ToInt32(Console.ReadLine());
  8. Console.WriteLine(num+"converts to");
  9. MulBase(num,baseNum);
  10. Console.WriteLine("Base"+baseNum);
  11. Console.ReadKey();
  12. }
  13. static void MulBase(int n,int b)
  14. {
  15. Stack digits = new Stack();
  16. do
  17. {
  18. digits.Push(n%b);
  19. n /= b;
  20. }while(n!=0);
  21. while(digits.Count>0)
  22. {
  23. Console.Write(digits.Pop());
  24. }
  25. }

4、火车进站调度重组问题在C#中的实现

问题描述:假设一列货运列车共有n节编号分别为1~n的车厢,在进站前这n节车厢并不是按其编号有序排列;现要求重新排列各车厢,使该列车在

进入车站时,所有的车厢从前到后按编号1~n的次序排列。

  1. interface IStack<T>
  2. {
  3. void Push(T item);//进栈操作
  4. T Pop();//出棧操作
  5. T Peek();//取数操作
  6. int GetLength();//求棧的长度
  7. bool IsEmpty();//判断棧是否为空
  8. void Clear();//清空棧操作
  9. }
  1. class SeqStack<T>:IStack<T>
  2. {
  3. //顺序栈的容量
  4. private int maxsize;
  5. //用于存储数序中的数据元素
  6. private T[] data;
  7. //指示顺序栈的栈顶
  8. private int top;
  9. //构建索引器
  10. public T this[int index]
  11. {
  12. get
  13. {
  14. return data[index];
  15. }
  16. set
  17. {
  18. data[index] = value;
  19. }
  20. }
  21. //棧容量属性
  22. public int Maxsize
  23. {
  24. get
  25. {
  26. return maxsize;
  27. }
  28. set
  29. {
  30. maxsize = value;
  31. }
  32. }
  33. //栈顶属性
  34. public int Top
  35. {
  36. get
  37. {
  38. return top;
  39. }
  40. }
  41. //初始化棧
  42. public SeqStack(int size)
  43. {
  44. data=new T[size];
  45. maxsize = size;
  46. top = -1;
  47. }
  48. //判断棧是否满
  49. public bool IsFull()
  50. {
  51. if (top == maxsize - 1)
  52. {
  53. return true;
  54. }
  55. else
  56. {
  57. return false;
  58. }
  59. }
  60. //判断棧是否为空
  61. public bool IsEmpty()
  62. {
  63. if (top == -1)
  64. {
  65. return true;
  66. }
  67. else
  68. {
  69. return false;
  70. }
  71. }
  72. //进栈操作
  73. public void Push(T item)
  74. {
  75. if (IsFull())
  76. {
  77. Console.WriteLine("Stack is full");
  78. return;
  79. }
  80. else
  81. {
  82. data[++top]=item;
  83. }
  84. }
  85. //出棧操作
  86. public T Pop()
  87. {
  88. T temp=default(T);
  89. if (IsEmpty())
  90. {
  91. Console.WriteLine("Stack is empty");
  92. return temp;
  93. }
  94. else
  95. {
  96. temp = data[top];
  97. --top;
  98. return temp;
  99. }
  100. }
  101. //获取栈顶元素
  102. public T Peek()
  103. {
  104. if(IsEmpty())
  105. {
  106. Console.WriteLine("Stack is empty");
  107. return default(T);
  108. }
  109. else
  110. {
  111. return data[top];
  112. }
  113. }
  114. //获取棧的长度
  115. public int GetLength()
  116. {
  117. return top + 1;
  118. }
  119. //清空棧
  120. public void Clear()
  121. {
  122. top = -1;
  123. }
  124. }
  1. class TrainAyyayrangeByStack
  2. {
  3. //车厢重排算法,K个缓冲铁轨,车厢初始排序存放在p中
  4. public bool Railroad(int[] p, int n, int k)
  5. {
  6. //重排成功返回true,否则返回false
  7. //创建与缓冲铁轨对应的堆栈
  8. SeqStack<int>[] H = new SeqStack<int>[k+1];
  9. for (int i = 1; i <= k;i++ )
  10. {
  11. H[i] = new SeqStack<int>(p.Length);
  12. }
  13. //初始化第一个出棧车厢号1
  14. int NowOut = 1;
  15. //初始设置缓冲铁轨中编号最小的车厢
  16. int minH = n+1;
  17. //初始minH号车厢对应的缓冲铁轨号
  18. int minS = 0;
  19. //车厢重排
  20. for (int i = 0; i < n;i++ )
  21. {
  22. //如果即将入站的车厢号和下一个即将出站的车厢号一致,就直接输出
  23. if (p[i] == NowOut)
  24. {
  25. Console.WriteLine("Move Car {0} from input to output", p[i]);
  26. //输出后将下一个即将出站的车厢号重置
  27. NowOut++;
  28. //从缓冲铁轨中输出
  29. while (minH == NowOut)
  30. {
  31. Output(ref minH, ref minS, ref H, k, n);
  32. NowOut++;
  33. }
  34. }
  35. //如果即将入站的车厢号和下一个即将出战的车厢号不一致,就将其保存在缓冲铁轨中
  36. else
  37. {
  38. //将p[i]送入某个缓冲铁轨
  39. if(!Hold(p[i],ref minH,ref minS,ref H,k,n))
  40. {
  41. return false;
  42. }
  43. }
  44. } return true;
  45. }
  46. //把车厢从缓冲铁轨送至出轨处,同时修改minS和minH
  47. void Output(ref int minH,ref int minS,ref SeqStack<int>[]H,int k,int n)
  48. {
  49. //车厢索引
  50. int c;
  51. //从堆栈minS中删除编号最小的车厢minH
  52. c = H[minS].Pop();
  53. Console.WriteLine("Move car {0} from holding track {1} to output",c,minS);
  54. //通过检查所有的栈顶,搜索新的minH和minS
  55. minH = n + 2;
  56. for (int i = 1; i <= k;i++ )
  57. {
  58. if(!H[i].IsEmpty()&&(H[i].Peek())<minH)
  59. {
  60. minH = H[i].Peek();
  61. minS = i;
  62. }
  63. }
  64. }
  65. //在一个缓冲铁轨中放入车厢c
  66. bool Hold(int c,ref int minH,ref int minS,ref SeqStack<int>[]H,int k,int n)
  67. {
  68. //如果没有可用的缓冲铁轨,则返回false
  69. //否则返回true
  70. //为车厢c寻找最优的缓冲铁轨
  71. //初始化最优铁轨和最优栈顶车厢号
  72. int BestTrack = 0;
  73. int BestTop = n + 1;
  74. //车厢索引
  75. int x;
  76. //扫描缓冲铁轨,寻找最优的缓冲铁轨棧,即栈顶元素相对最小
  77. for (int i = 1; i <= k;i++ )
  78. {
  79. //如果缓冲铁轨不为空
  80. if (!H[i].IsEmpty())
  81. {
  82. x = H[i].Peek();
  83. if (c < x && x < BestTop)
  84. {
  85. //铁轨i顶部的车厢编号最小
  86. BestTop = x;
  87. BestTrack = i;
  88. }
  89. }
  90. //铁轨i为空
  91. else
  92. {
  93. if(BestTrack==0)
  94. {
  95. BestTrack = i;
  96. }
  97. break;
  98. }
  99. }
  100. //没有可用铁轨
  101. if(BestTrack==0)
  102. {
  103. return false;
  104. }
  105. //把车厢c送入缓冲铁轨
  106. H[BestTrack].Push(c);
  107. Console.WriteLine("Move car {0} from input to holding track {1}",c,BestTrack);
  108. //如果条件成立就修改缓冲铁轨中下一个将要出站的车厢号
  109. if (c < minH)
  110. {
  111. minH = c;
  112. minS = BestTrack;
  113. }
  114. return true;
  115. }
  1. static void Main(string[] args)
  2. {
  3. int[] p = new int[] { 3,6,9,2,4,7,1,8,5};
  4. int k = 3;
  5. TrainAyyayrangeByStack ta = new TrainAyyayrangeByStack();
  6. bool result;
  7. result = ta.Railroad(p,p.Length,k);
  8.  
  9. do
  10. {
  11. if(result==false)
  12. {
  13. Console.WriteLine("need more holding track,please enter additional");
  14. k = k + Convert.ToInt32(Console.ReadLine());
  15. result = ta.Railroad(p,p.Length,k);
  16. }
  17. }while(result==false);
  18. Console.ReadKey();
  19. }

数据结构中的棧在C#中的实现的更多相关文章

  1. 面试题:java内存中的堆区和数据结构中的堆有什么区别

    java内存中的堆是一个  链表, 数据结构中的堆:就是一个栈

  2. jvm 中内存的栈和数据结构中的栈的区别

    1.常见的数据结构:栈.队列.数组.链表和红黑树,java内存划分 2.JYM中的栈是先进先出,先入栈的先执行: 2.数据结构中的栈是先进后出,类似手枪的弹夹,先进入的子弹最后才发射: 3.数据结构中 ...

  3. [Data Structure] 数据结构中各种树

    数据结构中有很多树的结构,其中包括二叉树.二叉搜索树.2-3树.红黑树等等.本文中对数据结构中常见的几种树的概念和用途进行了汇总,不求严格精准,但求简单易懂. 1. 二叉树 二叉树是数据结构中一种重要 ...

  4. 浅析数据结构中栈与C实现

    最近在搞摄像头驱动,o()︿︶)o 唉,别提有多烦,一堆寄存器就有人受的了--特么这不是单片机的开发,这是内核驱动开发-- 今天放松一下,我们来看看数据结构中的栈,这节的知识点可以说是数据结构中最容易 ...

  5. 使用JavaScript的数组实现数据结构中的队列与堆栈

    今天在项目中要使用JavaScript实现数据结构中的队列和堆栈,这里做一下总结. 一.队列和堆栈的简单介绍 1.1.队列的基本概念 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被 ...

  6. JavaScript学习总结(二十一)——使用JavaScript的数组实现数据结构中的队列与堆栈

    今天在项目中要使用JavaScript实现数据结构中的队列和堆栈,这里做一下总结. 一.队列和堆栈的简单介绍 1.1.队列的基本概念 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被 ...

  7. 数据结构中常用的排序算法 && 时间复杂度 && 空间复杂度

    第一部分:数据结构中常用的排序算法 数据结构中的排序算法一般包括冒泡排序.选择排序.插入排序.归并排序和 快速排序, 当然还有很多其他的排序方式,这里主要介绍这五种排序方式. 排序是数据结构中的主要内 ...

  8. SCIP:构造数据抽象--数据结构中队列与树的解释

    现在到了数学抽象中最关键的一步:让我们忘记这些符号所表示的对象.不应该在这里停滞不前,有许多操作可以应用于这些符号,而根本不必考虑它们到底代表着什么东西. --Hermann Weyi <思维的 ...

  9. 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率

    原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...

随机推荐

  1. OracleServiceORCL服务不见了怎么办

    用管理员身份运行命令提示符(CMD) 然后输入“oradim -new -sid orcl”即可

  2. sql server drop talbe 自动删除关联的外键 ,权限体系(二)

    alter table dbo.Sys_PowerTeamForUser add constraint FK_Sys_User_Sys_PowerTeamForUser foreign key (Sy ...

  3. A WebBrowser Toy

    原文:A WebBrowser Toy 记得上大学时,某老师为了防止学生上课不听讲,只准学生在课堂上看他放映的PPT,不准学生拷贝,而考试的内容恰恰是PPT上的内容,于是一个同学来找我,我就用VB写了 ...

  4. Atitit.软件GUIbutton与仪表盘--db数据库区--导入mysql sql错误的解决之道

    Atitit.软件GUIbutton与仪表盘--db数据库区--导入mysql sql错误的解决之道 Keyword::截取文本文件后部分 查看提示max_allowed_packet限制 Targe ...

  5. selenium之多线程启动grid分布式测试框架封装(三)

    七.工具类,线程监控器类创建 utils包中,创建java类:RemoteThreadStatusMonitor.java package com.lingfeng.utils; /** * 此监控器 ...

  6. php生成签名及验证签名

    <?php /** * 根据原文生成签名内容 * * @param string $data 原文内容 * * @return string * @author confu */ functio ...

  7. Net Framework中的提供的常用委托类型

    .Net Framework中的提供的常用委托类型   .Net Framework中提供有一些常用的预定义委托:Action.Func.Predicate.用到委托的时候建议尽量使用这些委托类型,而 ...

  8. Android在WebView上构建Web应用程序

    原文链接:http://developer.android.com/guide/webapps/webview.html reference:http://developer.android.com/ ...

  9. Extjs 组件继承 模板说明(同GridPanel案件)

    1. 重写initComponent()方法,并在该方法在调用父类的initComponent()方法.  如:subclass.superclass.initComponent.call(this) ...

  10. Reporting Service部署之访问权限

    原文:Reporting Service部署之访问权限 SQL Server Reporting Services 并非专门设计用于 Internet 报表部署方案,但是您可以成功地将 Reporti ...