• 数据结构和算法 – 3.堆栈和队列


    1.栈的实现

     

    后进先出

     

    image

     

    自己实现栈的代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections;
    
    namespace 数据结构和算法
    {
        //
        class CStack
        {
            private ArrayList list;
            private int p_index;
            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];
            }
    
            static void Main(string[] args)
            {
                //回文: sees倒过来还是sees
                CStack alist = new CStack();
                string ch;
                string word = "sees";
                bool ispalindrome = true;
                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;
                    }              
                    pos++;
                }
                if (ispalindrome)
                {
                    Console.WriteLine(word+" 是回文.");
                }
                else
                {
                    Console.WriteLine(word + " 不是回文.");
                }
    
               
                Console.ReadKey();
            }
        }
    }

    image

     

    2.Stack类(堆栈)

    Stack 类是 ICollection 接口的一个实现。它代表了一个 LIFO 群集或一个堆栈。此类在.NET 框架中是作为循环缓冲来实现的。这使得能动态地分配进栈数据项的空间。
    Stack 类包含进栈方法、出栈方法以及取值方法。此外,还有用于确定堆栈内元素数量的方法,清除堆栈全部数值的方法,以及把堆栈数值作为数组返回的方法。

     

    CopyTo 方法和 ToArray 方法

    CopyTo 方法会把堆栈内的内容复制到一个数组中。数组必须是 Object 类型,因为这是所有堆栈对象的数据类型。此方法会取走两个参数:一个数组和开始放置堆栈元素的数组的起始索引。堆栈内元素按照 LIFO 的顺序进行复制操作,就好像对它们进行出栈操作一样。下面这段代码说明了 CopyTo 方法的调用:

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

    ToArray 方法的工作原理与 CopyTo 方法类似。但是用户无法指定数组的起始索引位置,而是需要在赋值语句中创建新的数组。实例如下所示:
    Stack myStack = new Stack();
    for (int i = 0; i > 0; i++)
    myStack.Push(i);
    object[] myArray = new object[myStack.Count];
    myArray = myStack.ToArray();

     

    堆栈的实际操作

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    
    namespace 数据结构和算法
    {
        class 堆栈的操作
        {
            static void Main()
            {
                Stack nums = new Stack();
                Stack ops = new Stack();
                string expression = "5 + 10 + 15 +20";
                Calculate(nums, ops, expression);
                
                Console.WriteLine("Pop之前的数据:" + nums.Peek());
                nums.Push("1");
                Console.WriteLine("Pop的数据:" + nums.Pop());
                //nums.Push("1");
                Console.WriteLine("Pop之后的数据:" + nums.Peek());
                nums.Clear();
                if (nums.Count == 0)
                {
                    Console.WriteLine("Clear之后的数据为空");
                }
                else
                    Console.WriteLine("Clear之后的数据是否为空" + nums.Peek());
                Console.Read();
            }
    
            //IsNumeric isn'tbuilt into C# so we must define it
            static bool IsNumeric(string input)
            {
                bool flag = true;
                string pattern = (@"^d+$");
                Regex validate = new Regex(pattern);
                if (!validate.IsMatch(input))
                {
                    flag = false;
                }
                return flag;
            }
    
            static void Calculate(Stack N, Stack O, string exp)
            {
                string ch, token = "";
                for (int p = 0; p < exp.Length; p++)
                {
                    ch = exp.Substring(p, 1);
                    if (IsNumeric(ch))
                    {
                        token += ch; //+=
                    }
                    if (ch == " " || p == (exp.Length - 1))
                    {
                        if (IsNumeric(token))
                        {
                            N.Push(token);
                            token = "";
                        }
                    }
                    else if (ch == "+" || ch == "-" || ch == "*" || ch == "/")
                    {
                        O.Push(ch);
                    }
                    if (N.Count == 2)
                    {
                        Compute(N, O);
                    }
                }
            }
    
            static void Compute(Stack N, Stack O)
            {
                int oper1, 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 "/":
                        N.Push(oper1 / oper2);
                        break;
                }
            }
        }
    }

    image

     

     

    3.队列

    先进先出

    enQueue 排队

    deQueue 出队

    4.Queue类 (队列)

    在对一个新的 Queue 对象实例化的时候,队列默认的容量是 32 个数据项。根据定义,当队列已满时,其容量会双倍增长。这就意味着当队列最初达到满容量时,其新的容量值会变为 64。但是大家可以不用受这些数值的限制。
    在实例化对队列时,大家可以指定一个不同的初始容量值。
    Queue myQueue = new Queue(100);

    这个设置把队列的容量值设为了 100 个数据项。当然,大家也可以改变增长的倍数。增长倍数是传递给构造器的第二个参数,如下所示:
    Queue myQueue = new Queue(32, 3);

     

    用队列存储数据

    基数排序是通过对一组数据进行两遍排序来操作的。在这种情况下,整数的取值范围是从 0 到 99。第一遍是基于个位上的数字进行排序,而第二遍则是基于十位上的数字进行排序。然后,根据这些位置上的每个数字来把每一个数放置在一个箱子内。

    假设有下列这些数: 91、 46、 85、 15、 92、 35、 31、 22。

    image

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 数据结构和算法
    {
        class 用队列存储数据
        {
            enum DigitType { 
                //个位
                ones = 1, 
                //十位
                tens = 10 
            }
    
            //打印排序后的内容
            static void DisplayArray(int[] n)
            {
                for (int x = 0; x <= n.GetUpperBound(0); x++)
                    Console.Write(n[x] + " ");
            }
    
            //排序
            static void RSort(Queue[] que, int[] n, DigitType digit)
            {
                int snum;//下标
    
                for (int x = 0; x <= n.GetUpperBound(0); x++)
                {
                    if (digit == DigitType.ones)
                        snum = n[x] % 10;
                    else
                        snum = n[x] / 10;
                    que[snum].Enqueue(n[x]);
                }
            }
    
            static void BuildArray(Queue[] que, int[] n)
            {
                int y = 0;
                for (int x = 0; x <= 9; x++)
                    //que的下标count大于0的时候,替换n
                    while (que[x].Count > 0)
                    {
                        n[y] =
                        Int32.Parse(que[x].Dequeue().ToString());
                        y++;
                    }
            }
    
            static void Main(string[] args)
            {
                Queue[] numQueue = new Queue[10];
                int[] nums = new int[] { 91, 46, 85, 15, 92, 35, 31, 22 };
                int[] random = new Int32[99];
    
                DisplayArray(nums);
    
                // Display original list
                for (int i = 0; i < 10; i++)
                    numQueue[i] = new Queue();
    
                RSort(numQueue, nums, DigitType.ones);
                //numQueue, nums, 1
                BuildArray(numQueue, nums);
                Console.WriteLine();
                Console.WriteLine("第1次排序: ");
                //打印排序后的内容
                DisplayArray(nums);
                // Second pass sort
                RSort(numQueue, nums, DigitType.tens);
                BuildArray(numQueue, nums);
                Console.WriteLine();
                Console.WriteLine("第2次排序结果: ");
                //打印排序后的内容
                DisplayArray(nums);
                Console.WriteLine();
                Console.Write("Press enter to quit");
                Console.Read();
            }
        }
    }
    image

     

    image

     

    5. Queue 类的优先队列

     

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 数据结构和算法
    {
        public struct pqItem
        {
            //优先级
            public int priority;
            public string name;
        }
    
        public class PQueue : Queue
        {
            static void Main()
            {
                PQueue erwait = new PQueue();
                pqItem[] erPatient = new pqItem[3];
                pqItem nextPatient;
                erPatient[0].name = "刘在锡";
                erPatient[0].priority = 1;
                erPatient[1].name = "李光洙";
                erPatient[1].priority = 0;
                erPatient[2].name = "金钟国";
                erPatient[2].priority = 3;
    
                for (int x = 0; x <= erPatient.GetUpperBound(0); x++)
                    erwait.Enqueue(erPatient[x]);
    
                nextPatient = (pqItem)erwait.Dequeue();
    
                Console.WriteLine(nextPatient.name);
                Console.Read();
            }
    
            public PQueue()
            { }
    
            //重写出队
            public override object Dequeue()
            {
                object[] items;
    
                int min;
                items = this.ToArray();
                //假设第1个最小
                min = ((pqItem)items[0]).priority;
    
                for (int x = 1; x <= items.GetUpperBound(0); x++)
                    if (((pqItem)items[x]).priority < min)
                    {
                        min = ((pqItem)items[x]).priority;
                    }
    
                this.Clear();
    
                int x2;
    
                for (x2 = 0; x2 <= items.GetUpperBound(0); x2++)
                    if (((pqItem)items[x2]).priority == min && ((pqItem)items[x2]).name != "")
                        this.Enqueue(items[x2]);
    
                return base.Dequeue();
            }
        }
    
     
    }
    image
  • 相关阅读:
    iOS 怎么在一个函数执行完毕得到某个参数值后再去执行他下边的代码
    微信小程序开发(三)-----手动创建目录结构
    微信小程序开发(二)-----项目的创建
    微信小程序开发(一)-----工具的安装
    Block传值讲解与使用
    Mybatis xml约束文件的使用
    Spark Streaming 整合 Kafka
    Scala 大数据 常用算法收集
    WPF自定义动画控件 风机
    wpf 错误 执行了 QueryInterface 调用,请求提供 COM 可见的托管类“BoilerMonitoringV1._0.MapControl”的默认 IDispatch 接口。
  • 原文地址:https://www.cnblogs.com/tangge/p/5445358.html
Copyright © 2020-2023  润新知