基础数据类型

string & stringbuilder

  • string主要用于公共API、读取性能高、占用内存小;不可变,天然线程同步。
  • stringbuilder主要用于string拼接,修改性能好;可变,非线程同步。


数组

关键词:长度固定,顺序

以下代码演示内容

public class BasicDatatype : MonoBehaviour
{
//声明和初始化的3种方式
int[] array1 = new int[3] { 1, 4, 5 };
int[] array2;
int[] array3 = { 4, 6 };



// Start is called before the first frame update
void Start()
{
array2 = new int[6];//没有赋值的时候默认所有元素都是0;可以不赋值但是不能不指定长度
//以下展示数组遍历
for(int i=0; i<array1.Length; i++)
{
Debug.Log(array1[i]);
}
}

}


ArrayList

关键词:对象的有序集合、动态数组

对象是object类型,需要装箱和拆箱

动态意味着不用固定长度,会自动调整大小


以下代码演示的内容:

  • 声明和初始化
  • 增删改查
  • 常见属性:Count、Contains、IndexOf
  • 常见方法:Insert、Remove、Clear、Reverse、Sort

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

public class BasicDatatype : MonoBehaviour
{
//这是声明和初始化
ArrayList arrayList = new ArrayList();
int[] array = { 1, 7, 8 };
string[] str = { "kk", "pp" };

// Start is called before the first frame update
void Start()
{

//为动态数组添加单个元素
arrayList.Add(34);
arrayList.Add(18);
arrayList.Add(25);

//添加一个数组
arrayList.AddRange(array);
arrayList.AddRange(str);

//修改一个元素
arrayList[1] = 100;

//遍历动态数组
foreach(var v in arrayList)
{
Debug.Log(v);
}

//一些其他的常用属性
Debug.Log(arrayList.Count);//返回长度

print(arrayList.Contains(12));//返回布尔值

Debug.Log(arrayList.IndexOf(25));//返回元素的下标,这里应该返回2
Debug.Log(arrayList.IndexOf(2));//没有的话应该返回-1

//一些其他常用的方法
arrayList.Insert(1, 12);//在arraylist的第1位后面插入12
arrayList.Insert(0, "star");

arrayList.Remove(12);//第一次遇到的12将会被删掉;如果不包含这个值就没有作用

arrayList.Reverse();//逆转

//arrayList.Sort();//进行排序,但是如果前面的过程中没有控制好数据类型,比如我们这里加入了字符串,排序就会出错

arrayList.Clear();//清除其内容
}
}


List

关键词:泛型类集合

类似ArrayList,但是无需装箱和拆箱,类型安全

public class BasicDatatype : MonoBehaviour
{
List<int> list = new List<int>();

void Start()
{
list.Add(2);
list.Add(7);

Debug.Log(list.Count);
//很多内容都和arraylist很像,但是因为类型安全,所以更推荐用L
}
}


HashTable 哈希表

关键词:键值对

用object类型,和ArrayList一样,类型不安全


以下代码演示的内容:

  • 声明和初始化
  • 增删改查
  • 常见属性:Count、Contains、ContainsKey
  • 常见方法:Remove、Clear

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

public class BasicDatatype : MonoBehaviour
{
Hashtable ht = new Hashtable();

void Start()
{
//增
ht.Add("1", 100);
ht.Add("2", 300);
ht.Add(3, 800);

//删
ht.Remove(3);//清除键为3的键值对
ht.Clear();//全部清除

//改
ht["1"] = 900;

//查
Debug.Log(ht["1"]);

//获得所有的键
ICollection key = ht.Keys;

//遍历
foreach(var v in key)
{
Debug.Log(ht[v]);
}

//以下是属性
Debug.Log(ht.Count);//长度
Debug.Log(ht.ContainsKey("1"));//按键查找,返回布尔值
Debug.Log(ht.Contains(100));//按值查找,返回布尔值
}
}


Dictionary字典

关键词:用泛型类做键值对

以下两对关系很像:

  • HashTable(object类型,类型不安全)——>Dictionary(泛型,类型安全)
  • ArrayList(object类型,类型不安全)——>List(泛型,类型安全)

以下代码演示的内容:

  • 声明和初始化
  • 增删改查
  • 常见属性:Count、Contains、ContainsKey
  • 常见方法:Remove、Clear

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

public class BasicDatatype : MonoBehaviour
{
Dictionary<string, string> dic = new Dictionary<string, string>();

void Start()
{
//增
dic.Add("1", "200");
dic.Add("3", "600");

//删
dic.Remove("3");
dic.Clear();

//改
dic["3"] = "kk";

//查
Debug.Log(dic["3"]);

//常用属性
Debug.Log(dic.ContainsKey("1"));

//遍历
foreach(KeyValuePair<string, string> kvp in dic)
{
Debug.Log(kvp.Key + ":" + kvp.Value);
}
}
}


HashSet

关键词:不能重复的序列表

以下代码演示的内容:

  • 声明和初始化
  • 增删改查
  • 两个集合之间的运算

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

public class BasicDatatype : MonoBehaviour
{
HashSet<int> hs1 = new HashSet<int>();
HashSet<string> hs2 = new HashSet<string>();
HashSet<int> hs3 = new HashSet<int>();

void Start()
{
//增加
hs1.Add(1);
hs1.Add(2);
hs1.Add(2);

//计数
Debug.Log(hs1.Count);

hs3.Add(1);
hs3.Add(3);
hs3.Add(3);

//两个集合之间的运算
hs1.IntersectWith(hs3);//返回值是交集的部分
hs1.UnionWith(hs3);
hs1.ExceptWith(hs3);
hs1.SymmetricExceptWith(hs3);

//遍历
foreach (var v in hs1)
{
Debug.Log(v);
}
//没有自带的排序,想要排序只能走List
}
}


ListNode链表

关键词:泛型

  • list、数组的插入和删除需要移位,但是索引方便,不用遍历
  • 链表的插入和删除不用移位,但是索引的时候需要遍历

以下代码演示主要的代码功能:

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

public class BasicDatatype : MonoBehaviour
{
LinkedList<int> linkList = new LinkedList<int>();//声明一个链表
LinkedListNode<int> node;//声明一个节点
LinkedListNode<int> next;

void Start()
{
node = linkList.AddFirst(2);
linkList.AddAfter(node, 6);//在后面加
node = linkList.AddBefore(node, 1);//在前面加
next = linkList.AddAfter(node, 2);

//查
Debug.Log(linkList.Count);
Debug.Log(linkList.First.Value);
Debug.Log(linkList.Last.Value);

if (node.Previous != null)
Debug.Log(node.Previous.Value);

if (node.Next != null)
Debug.Log(node.Next.Value);

//插入
next = linkList.AddAfter(node, 3);
Debug.Log(node.Next.Value);
}
}


Stack

关键词:先进后出

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

public class BasicDatatype : MonoBehaviour
{
Stack st = new Stack();

void Start()
{
st.Push("a");
st.Push("b");
st.Push("c");

object top = st.Pop();//出栈
object peek = st.Peek();//拿到栈顶的元素

Debug.Log(top.ToString());
Debug.Log(peek.ToString());
Debug.Log(st.Count);//拿到数量

//遍历
foreach(var v in st)
{
Debug.Log(v);
}
}
}


Queue

关键词:先进先出

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

public class BasicDatatype : MonoBehaviour
{
Queue queue1 = new Queue();//object类型
Queue<int> queue2 = new Queue<int>();//泛型类

void Start()
{
//增
queue1.Enqueue("kkk");
queue1.Enqueue(3);

//删
Debug.Log(queue1.Dequeue());//输出kkk,也会改变queue1的值

//遍历
foreach (var v in queue1)
{
Debug.Log(v);
}
//其他的方法:Count/Contains/Clear也都有
}
}


手写堆栈和队列

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

class MyStack//这是一个栈
{

//这是栈里的每一个元素的数据类型,用链表来实现
class StackData
{
public StackData nextItem;//下一个
public object topData;//自己的值

public StackData(StackData next, object data)//这是构造函数
{
this.nextItem = next;//下一个
this.topData = data;//值
}
}

StackData top;//栈顶

//写Push方法
public void Push(object data)
{
top = new StackData(top, data);//入栈
}

public object Pop()
{
object obj = top.topData;
top = top.nextItem;
return obj;//拿到顶部的出栈数据
}
}


public class BasicDatatype : MonoBehaviour
{
void Start()
{
MyStack myStack = new MyStack();
myStack.Push(33);
myStack.Push("kkk");

object obj = myStack.Pop();
Debug.Log(obj.ToString());
}
}


队列

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

class MyQueue
{
class QueueData
{
public QueueData nextItem;
public object topData;

public QueueData(QueueData last, object data)
{
this.nextItem = last;
this.topData = data;
}

public QueueData(object data)
{
this.topData = data;
}
}

QueueData top;
QueueData last;

public void EnQueue(object data)
{
if (top == null)//如果队列为空
{
top = new QueueData(data);
last = top;
}

else
{
last = new QueueData(last, data);
}
}

public object DeQueue()
{
object obj = top.topData;
top = top.nextItem;
return obj;
}
}


public class BasicDatatype : MonoBehaviour
{
void Start()
{
MyQueue myQueue = new MyQueue();

myQueue.EnQueue("kkk");
myQueue.EnQueue("222");
myQueue.EnQueue(145);

Debug.Log(myQueue.DeQueue());//应该是kkk
}
}


树 & 二叉树

(1)概念

本质:树是n个节点的有限集,n=0时称为空树。在任意一棵非空树中,有且仅有一个根结点;当n大于1的时候,其余结点可以分为m个互不相交的有限集。是一种一对多的数据结构。

一些派生概念:

  • 结点的度:结点拥有的子树数量
  • 叶结点/终端结点:度为0 的结点
  • 非终端结点/分支结点/内部结点:度不为0的结点
  • 树的度(Degree):树内各结点的度的最大值
  • 树的深度/高度(Depth):树中结点的最大层次
  • 树的层次(Level):从根开始定义起,根为第一层,根的孩子是第二层
  • 有序树:各子树看成是从左到右有次序的;无序树:反之。

(2)特点

n>0的时候根节点是唯一的;m>0 的时候,子树的个数没有限制,但是一定是不相交的。

线性表和树的对比(图片来自《大话数据结构》一书):

数据结构梳理_数据结构


二叉树(Binary Tree)

(1)概念

二叉树是一种特殊的树,二叉树是n个结点的有限集合,该集合可以为空或由一个根节点和左右两个互不相交的二叉树组成。

(2)特点

  • 度是2
  • 左子树和右子树是有序的
  • 即使只有一棵树,仍然需要区分左子树和右子树

(3)各种形态

  • 斜树:分为左斜树(所有的结点都只有左子树的二叉树)和右叉树(所有的结点都只有右子树的二叉树);这就可以是线性表,线性表可以看作树的特殊表现形式。
  • 满二叉树:所有度不为0的结点都有左子树和右子树,并且所有的叶子都在同一层上。
  • 完全二叉树:可以理解为满二叉树的最底层可以是不满的
  • 同样结点数的二叉树,完全二叉树的深度是最小的
  • 叶子结点只出现在最下两层

(5)遍历二叉树

  • 前序遍历:根节点-左子树-右子树
  • 中序遍历:左子树-根节点-右子树
  • 后序遍历:右子树-根节点-左子树
  • 层序遍历:按层级来

Tips:中序序列可以与先序序列、后序序列、层序序列中的任意一个来构建唯一的二叉树。


  • 概念:由顶点和边组成
  • 顶点的度:和这个顶点相连的边的条数;有向图中可以分为出度和入度。
  • 权值:顶点和边的量化的属性,分为点权和边权
  • 分类:有向图(所有的边都有方向)和无向图(所有的边都是双向的)
  • 存储方式:邻接矩阵+邻接表
  • 操作:
  • 遍历:广度优先遍历(BFS)、深度优先遍历(DFS)