推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

在日常开发中,常常会用到数据集合,那么数据集合是什么呢,数据集合也没有想象中那么复杂。

数据集合就是专门用来存储数据、检索数据,以及对数据一系列操作的类。

这些类有:ArrayList数组、List列表、Queue队列、Dictionary字典、Hashtable哈希表、Stack堆栈。

在开发中,每种数据集合都有优缺点,今天就将这些数据集合进行归纳总结。

一是方便自己捋顺思路,二是可以帮助到对此理解不清晰的开发者。

这是本系列文章的第四篇:

【Unity3D数据集合】(一)数组集合Array学习
【Unity3D数据集合】(二)列表集合List及ListArray学习
【Unity3D数据集合】(三)字典Dictionary和哈希表Hashtable学习
【Unity3D数据集合】(四)堆栈Stack和队列Queue学习
【Unity3D数据集合】(五)链表LinkedList数据集合学习
【Unity3D数据集合】(六)散列集合HashSet和排序集合SortedSet学习
【Unity3D数据集合】(七)排序列表SortedList和排序字典SortedDictionary学习
【Unity3D数据集合】(八)点阵列BitArray学习

二、堆栈和队列集合介绍

1、堆栈Stack

堆栈Stack是一种数据结构,表现方式为数据先进后出,当需要对数据进行先进后出的操作是,可以使用堆栈。

那么什么是堆?什么是栈?什么是堆栈呢?

堆是无序的,是一片不连续的内存域,有用户自己来控制和释放,如果用户自己不释放的话,当内存达到一定的值时,程序就会通过垃圾回收机制GC来回收,程序运行期间动态分配的内存空间,可以根据需求来分配堆内存的大小。

栈是有顺序的,是一片连续的内存域,保持着先进后出的原则,有系统自动分配和维护,在编译时分配内存空间,所以栈初始化就需要定义大小。

有了堆和栈的概念,就可以知道堆栈是一种数据项按序排列的数据结构,只能在栈顶进行插入和删除,最后一个放入堆栈中的对象总是先被取出来,这个特性被称为后进先出(LIFO)。

堆栈的操作,实际上更像栈。

2、队列Queue

队列是一种特殊的线性表,它只能在表头进行删除操作,在表尾进行插入操作,也就是先进先出。

当需要对数据进行先进先出的操作时,队列是比较有效的。

当在列表中添加一项时,会插入到队尾,也被称为入队;当删除一项时,会在队头进行删除,也被称为出队。

三、堆栈和队列的区别

那么堆栈和队列之间有啥区别呢?

1、顺序的区别

堆栈采用先进后出FILO或者叫做后进先出LIFO的顺序进行操作。
队列采用先进先出FIFO的顺序进行操作

2、删除的区别

堆栈就像一个桶,无论是放水还是取水都是从最顶部开始,它下面的水要等后进来的水出来之后才能出来,只能在堆栈顶部作插入和删除的操作。

队列只能在对头进行删除操作,对队尾进行插入操作,就像是排队买菜一样。

四、堆栈和队列初始化

1、堆栈初始化

堆栈,主要使用System.Collections命名空间下的Stack创建集合:

Stack table = new Stack();

堆栈添加元素的类型是object类型,所以可以是String、Int,比如下面的例子:

using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Stack table;
    void Start()
    {
        table = new Stack();
        table.Push("A");
        table.Push("B");
        table.Push("C");
        table.Push("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

2、队列初始化

上面的例子已经演示了,如何初始化堆栈,如何添加数据,下面就看一下队列如何初始化:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Queue table;
    void Start()
    {
        table = new Queue();
        table.Enqueue("A");
        table.Enqueue("B");
        table.Enqueue("C");
        table.Enqueue("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

五、堆栈和队列的增删改查

1、查找数据

堆栈
因为堆栈只能最头部进行插入和删除操作,所以可以使用Peek()函数,弹出下一个可弹出的值:

using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Stack table;
    void Start()
    {
        table = new Stack();
        table.Push("A");
        table.Push("B");
        table.Push("C");
        table.Push("D");

        Debug.Log(table.Peek());
    }
}

通过循环寻找:

using System.Collections;
using System.Collections.Generic;//使用Hashtable时,必须引入这个命名空间
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Stack table;
    void Start()
    {
        table = new Stack();
        table.Push("A");
        table.Push("B");
        table.Push("C");
        table.Push("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

队列
因为队列只能在头部删除、尾部插入,所以可以使用Peek()函数,弹出下一个可弹出的值:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Queue table;
    void Start()
    {
        table = new Queue();
        table.Enqueue("A");
        table.Enqueue("B");
        table.Enqueue("C");
        table.Enqueue("D");

        Debug.Log(table.Peek());
    }
}

通过循环寻找:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Queue table;
    void Start()
    {
        table = new Queue();
        table.Enqueue("A");
        table.Enqueue("B");
        table.Enqueue("C");
        table.Enqueue("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

2、修改数据

堆栈

堆栈只能进行删除和插件操作,不能进行修改。

队列
队列先进先出操作,只能插入元素或者删除,不能进行修改。

3、增加数据

堆栈
可以通过Push()函数来增加数据:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Stack table;
    void Start()
    {
        table = new Stack();
        table.Push("A");
        table.Push("B");
        table.Push("C");
        table.Push("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

队列
可以通过Enqueue()函数来增加数据:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Queue table;
    void Start()
    {
        table = new Queue();
        table.Enqueue("A");
        table.Enqueue("B");
        table.Enqueue("C");
        table.Enqueue("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }

        table.Enqueue("E");

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

4、删除数据

堆栈
使用Pop()函数删除尾部数据元素:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Stack table;
    void Start()
    {
        table = new Stack();
        table.Push("A");
        table.Push("B");
        table.Push("C");
        table.Push("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }

        table.Pop();

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

队列
使用Dequeue函数删除头部数据元素:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    Queue table;
    void Start()
    {
        table = new Queue();
        table.Enqueue("A");
        table.Enqueue("B");
        table.Enqueue("C");
        table.Enqueue("D");

        foreach (string item in table)
        {
            Debug.Log(item);
        }

        Debug.Log(table.Dequeue());

        foreach (string item in table)
        {
            Debug.Log(item);
        }
    }
}

六、堆栈和队列的常见函数

堆栈常见函数

序号 方法名 & 描述
1 public virtual void Clear();
从 Stack 中移除所有的元素。
2 public virtual bool Contains( object obj );
判断某个元素是否在 Stack 中。
3 public virtual object Peek();
返回在 Stack 的顶部的对象,但不移除它。
4 public virtual object Pop();
移除并返回在 Stack 的顶部的对象。
5 public virtual void Push( object obj );
向 Stack 的顶部添加一个对象。
6 public virtual object[] ToArray();
复制 Stack 到一个新的数组中。

队列常见函数

序号 方法名 & 描述
1 public virtual void Clear();
从 Queue 中移除所有的元素。
2 public virtual bool Contains( object obj );
判断某个元素是否在 Queue 中。
3 public virtual object Dequeue();
移除并返回在 Queue 的开头的对象。
4 public virtual void Enqueue( object obj );
向 Queue 的末尾添加一个对象。
5 public virtual object[] ToArray();
复制 Queue 到一个新的数组中。
6 public virtual void TrimToSize();
设置容量为 Queue 中元素的实际个数。