zoukankan      html  css  js  c++  java
  • C#实现堆栈

    堆栈(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();
            }
        }
    }
  • 相关阅读:
    P2590 [ZJOI2008]树的统计(树链剖分)
    【算法】线性排序
    【LeetCode每天一题】Median of Two Sorted Arrays(两数组中的中位数)
    【算法】归并排序
    【LeetCode每天一题】Longest Substring Without Repeating Characters(最长无重复的字串)
    【算法】快排
    【LeetCode每天一题】Add Two Numbers(两链表相加)
    【LeetCode每天一题】Two Sum(两数之和)
    【算法】选择排序
    【算法】插入排序
  • 原文地址:https://www.cnblogs.com/greyhh/p/4812544.html
Copyright © 2011-2022 走看看