C#栈和队列的简介,算法与应用简单实例

C#栈和队列的简介

什么是栈和队列?

栈(Stack)和队列(Queue)是两种常用的数据结构,它们都是线性数据结构。

栈就像是一个箱子,我们往箱子里放入物品(压栈),并取出箱子里面的物品(弹栈)。

队列就像是一条排队的队伍,我们往队伍的尾部加入一个人(入队),并从队伍的头部取出一个人(出队)。

算法

栈(Stack)

1.入栈(Push):将一个元素加入栈顶。

2.出栈(Pop):删除栈顶的元素,同时返回这个元素。

3.查看栈顶元素(Peek):返回栈顶元素,但不删除它。

4.栈的判空(IsEmpty):判断栈是否为空,如果为空返回True,反之返回False。

队列(Queue)

1.入队(Enqueue):向队列尾部添加一个元素。

2.出队(Dequeue):返回队列头部的元素并将其从队列中删除。

3.查看队列头部元素(Peek):返回队列头部的元素,但不删除它。

4.队列的长度(Count):返回队列中元素的个数。

应用

栈(Stack)

1.平衡符号检查:检查表达式中的符号是否配对,如圆括号、方括号、大括号等。

示例代码:

public bool CheckSyntax(string expression)
{
    Stack<char> stack = new Stack<char>();

    foreach(char c in expression)
    {
        if(c == '(' || c == '{' || c == '[')
        {
            stack.Push(c);
        }
        else if(c == ')' || c == '}' || c == ']')
        {
            if(stack.Count == 0) return false;

            char top = stack.Pop();

            if((c == ')' && top != '(') || (c == '}' && top != '{') || (c == ']' && top != '['))
            {
                return false;
            }
        }
    }

    return stack.Count == 0;
}

2.逆波兰式计算器:将中缀表达式转换为后缀表达式(逆波兰式),然后用栈计算后缀表达式的值。

示例代码:

public double Calculate(string expression)
{
    Stack<double> stack = new Stack<double>();
    string[] tokens = expression.Split(' ');

    foreach(string token in tokens)
    {
        if(double.TryParse(token, out double number))
        {
            stack.Push(number);
        }
        else
        {
            double right = stack.Pop();
            double left = stack.Pop();

            switch(token)
            {
                case "+":
                    stack.Push(left + right);
                    break;
                case "-":
                    stack.Push(left - right);
                    break;
                case "*":
                    stack.Push(left * right);
                    break;
                case "/":
                    stack.Push(left / right);
                    break;
            }
        }
    }

    return stack.Pop();
}

队列(Queue)

1.广度优先搜索(BFS):在图或树等数据结构中进行的一种搜索算法,简单来说就是从起点开始,一层层向周围扩展,直到找到终点。

示例代码:

public void BFS(Node root)
{
    Queue<Node> queue = new Queue<Node>();
    HashSet<Node> visited = new HashSet<Node>();

    queue.Enqueue(root);
    visited.Add(root);

    while(queue.Count > 0)
    {
        Node node = queue.Dequeue();
        Console.WriteLine(node.Value);

        foreach(Node neighbor in node.Neighbors)
        {
            if(!visited.Contains(neighbor))
            {
                queue.Enqueue(neighbor);
                visited.Add(neighbor);
            }
        }
    }
}

2.生产者和消费者模式:利用队列实现线程间的协作,生产者负责生产数据,消费者负责消费数据,共同维护一个队列,生产者将数据放入队列尾部,消费者从队列头部取出数据。

示例代码:

public class ProducerConsumer
{
    private Queue<int> queue = new Queue<int>();
    private object locker = new object();

    public void Produce()
    {
        while(true)
        {
            int number = GenerateNumber();

            lock(locker)
            {
                queue.Enqueue(number);
                Console.WriteLine("Produced: " + number);
            }

            Thread.Sleep(1000);
        }
    }

    public void Consume()
    {
        while(true)
        {
            int number;

            lock(locker)
            {
                if(queue.Count == 0)
                    continue;

                number = queue.Dequeue();
                Console.WriteLine("Consumed: " + number);
            }

            Thread.Sleep(2000);
        }
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#栈和队列的简介,算法与应用简单实例 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • 聊聊Unity自定义组件之序列帧播放组件问题

    下面是“聊聊Unity自定义组件之序列帧播放组件问题”的完整攻略。 序列帧播放组件问题 问题描述 在使用Unity制作游戏时,我们经常需要用到序列帧播放,比如动画、特效等,如果每一帧都手动添加到游戏对象身上,这是一件非常繁琐的事情。因此,我们可以通过自定义一个序列帧播放组件来实现自动播放序列帧的效果。 但是在实现这一功能的过程中,我们可能会遇到一些问题,比如…

    C# 2023年6月3日
    00
  • C#拼图游戏编写代码(2)

    下面详细讲解如何编写C#拼图游戏的代码,具体分为以下步骤: 1. 创建WinForm窗口 代码中首先需要创建一个WinForm窗口,作为整个游戏的主界面。 public partial class FormMain : Form { public FormMain() { InitializeComponent(); } } 2. 添加拼图图片并进行切割 接…

    C# 2023年5月15日
    00
  • C#实现一个控制台的点餐系统

    C#实现一个控制台的点餐系统完整攻略 需求分析 点餐系统需要实现以下功能: 展示菜单 输入点餐内容和数量 确认订单及计算总价 退出程序 设计实现 数据结构 点餐系统需要用到的数据结构有: 菜品类别 Category 菜品类 Dish 菜单类 Menu 订单类 Order 具体定义如下: // 菜品类别 public enum Category { 饮料, 小…

    C# 2023年6月7日
    00
  • C# 对象持久化详解

    C# 对象持久化详解 什么是对象持久化 对象持久化是指将内存中的对象数据转换为持久化存储的数据,以便在程序关闭后仍然能够重新读取数据。这种方式常用于数据存储,包括关系数据库等。 C# 中的对象持久化 在 C# 中,我们可以使用多种方式实现对象持久化,最常用的方式是使用 Entity Framework 和 JSON 序列化。 使用 Entity Framew…

    C# 2023年5月31日
    00
  • C#通过GET/POST方式发送Http请求

    下面我将为你详细讲解“C#通过GET/POST方式发送HTTP请求”的完整攻略。 1. 使用HttpWebRequest类发送GET请求 发送GET请求需要使用HttpWebRequest类。下面是发送GET请求的示例代码: string url = "https://example.com/api/"; HttpWebRequest r…

    C# 2023年5月31日
    00
  • 改进c# 代码的五个技巧(一)

    当我们编写C#代码时,既希望代码功能完善,也希望代码运行速度和内存占用量方面尽可能优化。在这篇文章中,我们会介绍五个技巧,可以帮助你改进C#代码的质量。 技巧一:使用StringBuilder代替String 使用String类型声明的变量在处理文本时会创建一个新的字符串对象,如果需要在原始字符串上添加字符,则需要使用连接符+。这样使用+连接字符串会导致系统…

    C# 2023年5月15日
    00
  • asp.net获取当前网址url的各种属性(文件名、参数、域名 等)的代码

    当ASP.NET页面和控件运行时,可以通过Request对象的属性来获取当前网址的各种属性。 以下是获取当前网址url的一些常用属性: 获取当前页面的URL Request.Url.AbsoluteUri 该属性返回当前页面的完整URL,包括协议、域名、端口号、路径和查询字符串。如:https://www.example.com/test.aspx?id=1…

    C# 2023年5月31日
    00
  • Winform窗体如何改变语言类型

    Winform 窗体的语言设置主要涉及以下两方面: 改变窗体语言的方式 处理措施 下面我们将会讲解如何进行以上两个方面设置。 改变窗体语言的方式 Winforms 默认依赖系统语言,在资源文件中保存语言翻译。有三种常见方式实现表单翻译: 静态文本资源文件 动态文本资源文件 使用第三方库 静态文本资源文件 使用静态文本资源文件时,我们在应用程序中会有一个包含预…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部