c# 插入数据到 uniqueidentifier_每天5分钟用C#学习数据结构(10)栈 Part 1

27da963be108f1090e3feb676a175520.png 【基础知识作者  / Edison Zhou 这是 恰童鞋骚年 的第 199 篇原创文章
上一篇 完成了基本的线性表部分的介绍,本篇开始学习一个特殊的线性表结构:栈 。 1栈的初体验

现实生活中的事情往往都能总结归纳成一定的数据结构,例如餐馆中餐盘的堆叠和使用,羽毛球筒里装的羽毛球等都是典型的栈结构。而在.NET中,值类型在线程栈上进行分配,引用类型在托管堆上进行分配,本文所说的“栈”正是这种数据结构。栈和队列都是常用的数据结构,它们的逻辑结构与线性表相通,不同之处则在于操作受某种特殊限制。因此,栈和队列也被称为操作受限的线性表。这里,我们首先来了解一下栈。

 栈的基本特征

351efcb90d9c552c70312625e779bfde.png

栈(stack)是限定仅在表尾进行插入和删除操作的线性表。其特点是:“后进先出“或“先进后出”。

 栈的基本操作

(1)栈的插入操作,叫作进栈,也称压栈、入栈:

836f07ad90decc65e5661cd09f1d8d52.png

(2)栈的删除操作,叫作出栈,也有的叫作弹栈:

e9211297ae09720564b5b7202ca89284.png

2栈的基本实现(顺序存储) 既然栈属于特殊的线性表,那么其实现也会有两种形式:顺序存储结构和链式存储结构。首先,对于Stack,我们希望能够提供以下几个方法供调用:
Stack()创建一个空的栈
void Push(T s)往栈中添加一个新的元素
T Pop()移除并返回最近添加的元素
bool IsEmpty()栈是否为空
int Size()栈中元素的个数

对于顺序存储,我们可以参照顺序表的实现方式,借助数组来存储各个数据元素,然后对这个数组进行一定的封装,提供指定的操作对数据元素进行插入和删除即可。

(1)入栈操作实现

c168476861d17ef38df0501bfa3a463b.png

代码如下:

/// /// 入栈/// /// 节点元素public void Push(T node){    if (index == nodes.Length)    {        // 增大数组容量        ResizeCapacity(nodes.Length * 2);    }    nodes[index] = node;    index++;}

借助数组来实现入栈操作,其关键之处就在于top指针的移动。这里index初始值为0,每次入栈一个则将index加1,即指向下一个即将入栈的位置。由于这里采用了动态扩容的机制,所以没有判断栈中元素个数是否达到了最大值。

(2)出栈操作实现

出栈操作需要先去的要出栈的元素,然后将index减1,即指向下一个即将出栈的元素的位置。

/// /// 出栈/// /// 出栈节点元素public T Pop(){    if(index == 0)    {        return default(T);    }    T node = nodes[index - 1];    index--;    nodes[index] = default(T);    if (index > 0 && index == nodes.Length / 4)    {        // 缩小数组容量        ResizeCapacity(nodes.Length / 2);    }    return node;}

这里首先需要判断index是否已经到达了最小值,出栈的元素位置需要置为默认值(如果是int数组,那么会重置为0),最后返回出栈的元素对象。这里当元素个数小于数组的四分之一时会进行容量收缩操作。

(3)完整的类实现

/// /// 基于数组的栈实现/// /// 类型public class MyArrayStack{    private T[] nodes;    private int index;    public MyArrayStack(int capacity){        this.nodes = new T[capacity];        this.index = 0;    }    ///     /// 入栈    ///     /// 节点元素    public void Push(T node){        if (index == nodes.Length)        {            // 增大数组容量            ResizeCapacity(nodes.Length * 2);        }        nodes[index] = node;        index++;    }    ///     /// 出栈    ///     /// 出栈节点元素    public T Pop(){        if(index == 0)        {            return default(T);        }        T node = nodes[index - 1];        index--;        nodes[index] = default(T);        if (index > 0 && index == nodes.Length / 4)        {            // 缩小数组容量            ResizeCapacity(nodes.Length / 2);        }        return node;    }    ///     /// 重置数组大小    ///     /// 新的容量    private void ResizeCapacity(int newCapacity){        T[] newNodes = new T[newCapacity];        if(newCapacity > nodes.Length)        {            for (int i = 0; i < nodes.Length; i++)            {                newNodes[i] = nodes[i];            }        }        else        {            for (int i = 0; i < newCapacity; i++)            {                newNodes[i] = nodes[i];            }        }        nodes = newNodes;    }    ///     /// 栈是否为空    ///     /// true/false    public bool IsEmpty(){        return this.index == 0;    }    ///     /// 栈中节点个数    ///     public int Size    {        get        {            return this.index;        }    }}

(4)简单的功能测试

首先,顺序入栈10个随机数,输出其元素个数与是否为空;

然后依次出栈,输出每个数据元素;

最后,再入栈15个随机数并出栈输出。

/// /// 基于数组的栈的测试/// static void StackWithArrayTest(){    MyArrayStack<int> stack = new MyArrayStack<int>(10);    Console.WriteLine(stack.IsEmpty());    Random rand = new Random();    for (int i = 0; i < 10; i++)    {        stack.Push(rand.Next(1, 10));    }    Console.WriteLine("IsEmpty:{0}",stack.IsEmpty());    Console.WriteLine("Size:{0}", stack.Size);    Console.WriteLine("-------------------------------");    for (int i = 0; i < 10; i++)    {        int node = stack.Pop();        Console.Write(node + " ");    }    Console.WriteLine();    Console.WriteLine("IsEmpty:{0}", stack.IsEmpty());    Console.WriteLine("Size:{0}", stack.Size);    Console.WriteLine("-------------------------------");    for (int i = 0; i < 15; i++)    {        stack.Push(rand.Next(1, 15));    }    for (int i = 0; i < 15; i++)    {        int node = stack.Pop();        Console.Write(node + " ");    }    Console.WriteLine();}

运行结果如下所示:

4ad4a7c6b076489d50258a34ac2907da.png

3小结

本文介绍了栈的基本概念及顺序存储的实现,下一篇会介绍链式存储的实现!

4参考资料 程杰,《大话数据结构》 陈广,《数据结构(C#语言描述)》 段恩泽,《数据结构(C#语言版)》 往期 精彩 回顾

每天5分钟用C#学习数据结构(9)

每天5分钟用C#学习数据结构(8)

每天5分钟用C#学习数据结构(7)

基于Jenkins的开发测试全流程持续集成实践

基于Jenkins的ASP.NET Core持续集成实践

665e235967e3ca727eaf7c0b2b91612a.png

点个“在看”/转发朋友圈就是对我最大的支持

22c77c8bf64422772bf7bb1b593f9ca4.png

?点击

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值