数据结构中的棧在C#中的实现
数据结构中的棧在C#中的实现
一、大致学习
棧是一种面向表的数据结构,棧中的数据只能在标的某一短进行添加和删除操作,是一种典型的(LIFO)数据结构。
现实生活中的理解:自助餐厅的盘子堆,人们总是从顶部取走盘子,当洗碗工把洗好的盘子放回盘子堆的时候也是放在盘子堆的顶部。
Stack类实现棧:Stack<T> number=new Stack<T>();
Stack类是ICollection接口的一个实现(foreach),它代表了一个LIFO群集或一个棧,在.NET中作为循环缓冲来实现的,这使得能动态地分配进栈数据项的空间;
Stack构造器方法,默认的构造器实例化的是一个具有10个数值初始容量的空栈,每当棧达到满容量时就会把容量值翻倍;另一种构造器允许创建一个来自另一个群集对象的棧对象
如:
- string [] names= new string[]{"jack","rose","jeff"};
- Stack nameStack=new Stack(names);
二、具体分析
C#Stack泛型类的常用方法介绍:
1、Push(object item)方法:将对象插入栈顶,同时将棧的初始变量+1
- public void Push(object item)
- {
- list.Add(item);
- p_index++;
- }
2、Pop()方法:将对象移除栈顶,同时将棧的初始变量-1,返回出棧的对象

- public object Pop()
- {
- object obj=list[p_index];
- list.RemoveAt(p_index);
- p_index--;
- return obj;
- }

3、Peek()方法:取数,只是查看栈顶元素的”值“
- public object Peek()
- {
- return list[p_index];
- }
4、Clear()方法:清空棧内数据,将数据项计数器设置为0
- public void Clear()
- {
- list.Clear();
- p_index = -1;
- }
5、Contains()方法:用来确定指定的元素是否在棧内 bool
- public bool Contains(object item)
- {
- return list.Contains(item);
- }
6、CopyTo()方法:将棧内的内容复制到一个数组中,要求数组必须是object类型的,因为这是所有棧对象的数据类型。包含两个参数:一个数组和起始索引值

- Stack myStack=new Stack();
- for(int i=20;i>0;i--)
- {
- myStack.Push(i);
- }
- object [] myArray=new object[myStack.Count];
- myStack.CopyTo(myArray,0);

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

- Stack myStack=new Stack();
- for(int i=0;i>0;i++)
- {
- myStack.Push(i);
- }
- object [] myArray=new object[myStack.Count];
- myArray=myStack.ToArray();

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

- public int Count
- {
- get
- {
- return list.Count;
- }
- }

三、案例分析
1、使用棧来判断回文
把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。

- class CStack
- {
- private int p_index;
- private ArrayList list;
- public CStack()
- {
- list = new ArrayList();
- p_index = -1;
- }
- //获取棧的空间
- public int Count
- {
- get
- {
- return list.Count;
- }
- }
- //进栈
- public void Push(object item)
- {
- list.Add(item);
- p_index++;
- }
- //出棧
- public object Pop()
- {
- object obj=list[p_index];
- list.RemoveAt(p_index);
- p_index--;
- return obj;
- }
- //清空棧内元素
- public void Clear()
- {
- list.Clear();
- p_index = -1;
- }
- //取数
- public object Peek()
- {
- return list[p_index];
- }
- public bool Contains(object item)
- {
- return list.Contains(item);
- }
- }


- static void Main(string[] args)
- {
- CStack alist = new CStack();
- string ch;
- string word = "woainiiniaow";
- bool isPalindrome = true;
- //将word反转存入棧中
- for (int i = 0; i < word.Length;i++ )
- {
- alist.Push(word.Substring(i,1));
- }
- //进行判断
- int pos = 0;
- while(alist.Count>0)
- {
- ch = alist.Pop().ToString();
- if (ch != word.Substring(pos, 1))
- {
- isPalindrome = false;
- break;
- }
- else
- {
- pos++;
- }
- }
- if (isPalindrome)
- {
- Console.WriteLine("{0}是回文", word);
- }
- else
- {
- Console.WriteLine("{0}不是回文", word);
- }
- Console.ReadKey();
- } //另外我觉得可采用另一种常规方法就是复制一个“数组”,原“数组”从0->Length遍历,新“数组”从Length->0遍历,进行比对。

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

- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Collections;
- namespace _09使用棧来实现四则运算
- {
- class Program
- {
- static void Main(string[] args)
- {
- Stack nums = new Stack();
- Stack ops = new Stack();
- string expression = "5*2";
- Calculate(nums,ops,expression);
- Console.WriteLine(nums.Pop());
- Console.ReadKey();
- }
- /// <summary>
- /// 判断是否是数字
- /// </summary>
- /// <param name="input">要判断参数</param>
- /// <returns></returns>
- static bool IsNumeric(string input)
- {
- bool flag = true;
- string pattern=(@"^\d+$");
- Regex validate = new Regex(pattern);
- if(!validate.IsMatch(input))
- {
- flag = false;
- }
- return flag;
- }
- /// <summary>
- /// 进栈操作
- /// </summary>
- /// <param name="N">保存数字的棧</param>
- /// <param name="O">保存运算符的棧</param>
- /// <param name="exp">运算表达式</param>
- static void Calculate(Stack N,Stack O,string exp)
- {
- string ch, token = "";
- for (int i = 0; i < exp.Length;i++ )
- {
- ch = exp.Substring(i,1);
- if (IsNumeric(ch))
- {
- token = ch;
- N.Push(token);
- token = "";
- }
- //if(ch==""||i==(exp.Length-1))
- //{
- // N.Push(token);
- // token = "";
- //}
- else if(ch=="+"||ch=="-"||ch=="*"||ch=="/")
- {
- O.Push(ch);
- }
- if(N.Count==2)
- {
- Compute(N,O);
- }
- }
- }
- /// <summary>
- /// 进行运算
- /// </summary>
- /// <param name="N">参与运算的数字的棧</param>
- /// <param name="O">参与运算的运算符的棧</param>
- static void Compute(Stack N,Stack O)
- {
- int oper1;
- int oper2;
- string oper;
- oper1 = Convert.ToInt32(N.Pop());
- oper2 = Convert.ToInt32(N.Pop());
- oper = Convert.ToString(O.Pop());
- switch(oper)
- {
- case"+":
- N.Push(oper1+oper2);
- break;
- case "-":
- N.Push(oper1-oper2);
- break;
- case "*":
- N.Push(oper1*oper2);
- break;
- case "/":
- if (oper2 == 0)
- {
- throw new Exception("除数不能为0");
- }
- N.Push(oper1/oper2);
- break;
- }
- }
- }
- }

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

- static void Main(string[] args)
- {
- int num, baseNum;
- Console.Write("Enter a decimal number");
- num = Convert.ToInt32(Console.ReadLine());
- Console.Write("Enter a base");
- baseNum = Convert.ToInt32(Console.ReadLine());
- Console.WriteLine(num+"converts to");
- MulBase(num,baseNum);
- Console.WriteLine("Base"+baseNum);
- Console.ReadKey();
- }
- static void MulBase(int n,int b)
- {
- Stack digits = new Stack();
- do
- {
- digits.Push(n%b);
- n /= b;
- }while(n!=0);
- while(digits.Count>0)
- {
- Console.Write(digits.Pop());
- }
- }

4、火车进站调度重组问题在C#中的实现
问题描述:假设一列货运列车共有n节编号分别为1~n的车厢,在进站前这n节车厢并不是按其编号有序排列;现要求重新排列各车厢,使该列车在
进入车站时,所有的车厢从前到后按编号1~n的次序排列。

- interface IStack<T>
- {
- void Push(T item);//进栈操作
- T Pop();//出棧操作
- T Peek();//取数操作
- int GetLength();//求棧的长度
- bool IsEmpty();//判断棧是否为空
- void Clear();//清空棧操作
- }


- class SeqStack<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 SeqStack(int size)
- {
- data=new T[size];
- maxsize = size;
- top = -1;
- }
- //判断棧是否满
- public bool IsFull()
- {
- if (top == maxsize - 1)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- //判断棧是否为空
- public bool IsEmpty()
- {
- if (top == -1)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- //进栈操作
- public void Push(T item)
- {
- if (IsFull())
- {
- Console.WriteLine("Stack is full");
- return;
- }
- else
- {
- data[++top]=item;
- }
- }
- //出棧操作
- public T Pop()
- {
- T temp=default(T);
- if (IsEmpty())
- {
- Console.WriteLine("Stack is empty");
- return temp;
- }
- else
- {
- temp = data[top];
- --top;
- return temp;
- }
- }
- //获取栈顶元素
- public T Peek()
- {
- if(IsEmpty())
- {
- Console.WriteLine("Stack is empty");
- return default(T);
- }
- else
- {
- return data[top];
- }
- }
- //获取棧的长度
- public int GetLength()
- {
- return top + 1;
- }
- //清空棧
- public void Clear()
- {
- top = -1;
- }
- }


- class TrainAyyayrangeByStack
- {
- //车厢重排算法,K个缓冲铁轨,车厢初始排序存放在p中
- public bool Railroad(int[] p, int n, int k)
- {
- //重排成功返回true,否则返回false
- //创建与缓冲铁轨对应的堆栈
- SeqStack<int>[] H = new SeqStack<int>[k+1];
- for (int i = 1; i <= k;i++ )
- {
- H[i] = new SeqStack<int>(p.Length);
- }
- //初始化第一个出棧车厢号1
- int NowOut = 1;
- //初始设置缓冲铁轨中编号最小的车厢
- int minH = n+1;
- //初始minH号车厢对应的缓冲铁轨号
- int minS = 0;
- //车厢重排
- 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;
- }
- //把车厢从缓冲铁轨送至出轨处,同时修改minS和minH
- void Output(ref int minH,ref int minS,ref SeqStack<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",c,minS);
- //通过检查所有的栈顶,搜索新的minH和minS
- minH = n + 2;
- for (int i = 1; i <= k;i++ )
- {
- if(!H[i].IsEmpty()&&(H[i].Peek())<minH)
- {
- minH = H[i].Peek();
- minS = i;
- }
- }
- }
- //在一个缓冲铁轨中放入车厢c
- bool Hold(int c,ref int minH,ref int minS,ref SeqStack<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].Peek();
- if (c < x && x < BestTop)
- {
- //铁轨i顶部的车厢编号最小
- BestTop = x;
- BestTrack = i;
- }
- }
- //铁轨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;
- }


- static void Main(string[] args)
- {
- int[] p = new int[] { 3,6,9,2,4,7,1,8,5};
- int k = 3;
- TrainAyyayrangeByStack ta = new TrainAyyayrangeByStack();
- bool result;
- result = ta.Railroad(p,p.Length,k);
- do
- {
- if(result==false)
- {
- Console.WriteLine("need more holding track,please enter additional");
- k = k + Convert.ToInt32(Console.ReadLine());
- result = ta.Railroad(p,p.Length,k);
- }
- }while(result==false);
- Console.ReadKey();
- }

数据结构中的棧在C#中的实现的更多相关文章
- 面试题:java内存中的堆区和数据结构中的堆有什么区别
java内存中的堆是一个 链表, 数据结构中的堆:就是一个栈
- jvm 中内存的栈和数据结构中的栈的区别
1.常见的数据结构:栈.队列.数组.链表和红黑树,java内存划分 2.JYM中的栈是先进先出,先入栈的先执行: 2.数据结构中的栈是先进后出,类似手枪的弹夹,先进入的子弹最后才发射: 3.数据结构中 ...
- [Data Structure] 数据结构中各种树
数据结构中有很多树的结构,其中包括二叉树.二叉搜索树.2-3树.红黑树等等.本文中对数据结构中常见的几种树的概念和用途进行了汇总,不求严格精准,但求简单易懂. 1. 二叉树 二叉树是数据结构中一种重要 ...
- 浅析数据结构中栈与C实现
最近在搞摄像头驱动,o()︿︶)o 唉,别提有多烦,一堆寄存器就有人受的了--特么这不是单片机的开发,这是内核驱动开发-- 今天放松一下,我们来看看数据结构中的栈,这节的知识点可以说是数据结构中最容易 ...
- 使用JavaScript的数组实现数据结构中的队列与堆栈
今天在项目中要使用JavaScript实现数据结构中的队列和堆栈,这里做一下总结. 一.队列和堆栈的简单介绍 1.1.队列的基本概念 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被 ...
- JavaScript学习总结(二十一)——使用JavaScript的数组实现数据结构中的队列与堆栈
今天在项目中要使用JavaScript实现数据结构中的队列和堆栈,这里做一下总结. 一.队列和堆栈的简单介绍 1.1.队列的基本概念 队列:是一种支持先进先出(FIFO)的集合,即先被插入的数据,先被 ...
- 数据结构中常用的排序算法 && 时间复杂度 && 空间复杂度
第一部分:数据结构中常用的排序算法 数据结构中的排序算法一般包括冒泡排序.选择排序.插入排序.归并排序和 快速排序, 当然还有很多其他的排序方式,这里主要介绍这五种排序方式. 排序是数据结构中的主要内 ...
- SCIP:构造数据抽象--数据结构中队列与树的解释
现在到了数学抽象中最关键的一步:让我们忘记这些符号所表示的对象.不应该在这里停滞不前,有许多操作可以应用于这些符号,而根本不必考虑它们到底代表着什么东西. --Hermann Weyi <思维的 ...
- 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率
原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...
随机推荐
- OracleServiceORCL服务不见了怎么办
用管理员身份运行命令提示符(CMD) 然后输入“oradim -new -sid orcl”即可
- sql server drop talbe 自动删除关联的外键 ,权限体系(二)
alter table dbo.Sys_PowerTeamForUser add constraint FK_Sys_User_Sys_PowerTeamForUser foreign key (Sy ...
- A WebBrowser Toy
原文:A WebBrowser Toy 记得上大学时,某老师为了防止学生上课不听讲,只准学生在课堂上看他放映的PPT,不准学生拷贝,而考试的内容恰恰是PPT上的内容,于是一个同学来找我,我就用VB写了 ...
- Atitit.软件GUIbutton与仪表盘--db数据库区--导入mysql sql错误的解决之道
Atitit.软件GUIbutton与仪表盘--db数据库区--导入mysql sql错误的解决之道 Keyword::截取文本文件后部分 查看提示max_allowed_packet限制 Targe ...
- selenium之多线程启动grid分布式测试框架封装(三)
七.工具类,线程监控器类创建 utils包中,创建java类:RemoteThreadStatusMonitor.java package com.lingfeng.utils; /** * 此监控器 ...
- php生成签名及验证签名
<?php /** * 根据原文生成签名内容 * * @param string $data 原文内容 * * @return string * @author confu */ functio ...
- Net Framework中的提供的常用委托类型
.Net Framework中的提供的常用委托类型 .Net Framework中提供有一些常用的预定义委托:Action.Func.Predicate.用到委托的时候建议尽量使用这些委托类型,而 ...
- Android在WebView上构建Web应用程序
原文链接:http://developer.android.com/guide/webapps/webview.html reference:http://developer.android.com/ ...
- Extjs 组件继承 模板说明(同GridPanel案件)
1. 重写initComponent()方法,并在该方法在调用父类的initComponent()方法. 如:subclass.superclass.initComponent.call(this) ...
- Reporting Service部署之访问权限
原文:Reporting Service部署之访问权限 SQL Server Reporting Services 并非专门设计用于 Internet 报表部署方案,但是您可以成功地将 Reporti ...