zoukankan      html  css  js  c++  java
  • 数据结构中的棧在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();
            }
    复制代码

  • 相关阅读:
    JavaScript 为字符串添加样式 【每日一段代码80】
    JavaScript replace()方法 【每日一段代码83】
    JavaScript for in 遍历数组 【每日一段代码89】
    JavaScript 创建用于对象的模板【每日一段代码78】
    html5 css3 新元素简单页面布局
    JavaScript Array() 数组 【每日一段代码88】
    JavaScript toUTCString() 方法 【每日一段代码86】
    位运算
    POJ 3259 Wormholes
    POJ 3169 Layout
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3193195.html
Copyright © 2011-2022 走看看