greyhh

记录学习中的点点滴滴

导航

C#实现堆栈

Posted on 2015-09-16 10:47  greyhh  阅读(265)  评论(0编辑  收藏  举报

堆栈(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;
            }
            else
                return false;
        }
        //判断栈是否为满
        public bool IsFull()
        {
            if (top == maxsize - 1)
            {
                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 + 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;
        }

        //在一个缓冲区中放入车厢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 = 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 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 + 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;
            else
                return 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;
        }

        //在一个缓冲铁轨中放入车厢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 = 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 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 + 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();
        }
    }
}