文章目录
数据结构学习(三)栈和队列
编码部分使用C#,对于学过面向对象来说,看起来应该很简单。重点是学习栈这种数据结构,了解栈的特性,如果能写一个栈的话那就更好了。
1. 队列
1.1 认识队列
先进先出。元素从队尾进,从队首出。只允许在队首进行删除,在队尾进行添加操作。
队尾:
队首:
了解:优先队列(可插队)
…略
1.2 借助数组实现一个队列
这里我们借助数组来实现一个队列。C# 有已经实现好的队列,我们直接看它的API,照猫画虎来定义我们自定义的队列的API。
using System;
using System.Collections;
namespace ConsoleAppDemo
{
// 借助数组实现一个简单的队列
public class MMArrayQueue<T> // 队列中存储泛型类型的数据
{
private ArrayList array;
// 初始化(不带参数)
public MMArrayQueue()
{
array = new ArrayList();
}
// 初始化(带参数)
public MMArrayQueue(int capacity)
{
array = new ArrayList(capacity);
}
// 是否为空
public bool IsEmpty()
{
return (array.Count <= 0);
}
// 当前容量
public int GetSize()
{
return array.Count;
}
// 队首元素
public T GetFront()
{
if (this.IsEmpty())
{
return default;
}
return (T)array[0];
}
// 入队
public void Enqueue(T t)
{
array.Add(t);
}
// 出队
public void Dequeue()
{
array.RemoveAt(0);
}
}
}
这样的话一个简单的队列就实现了,其实实现一个队列不用这么复杂的,只要有数组,就能实现队列。思路就是上面代码所述。
2. 栈
2.1 认识栈
先进后出。元素从栈顶进,从栈顶出。
栈顶
栈底
压栈/入栈:即入栈,元素从栈顶进入
出栈:站定元素出栈
可以通过数组或者链表等数据结构来实现栈。
…略
2.2 借助数组实现一个栈
这里我们借助数组来实现一个简单的栈
using System;
using System.Collections;
namespace ConsoleAppDemo
{
// 借助数组实现一个简单的栈
public class MMArrayStack<T>
{
private ArrayList array;
// 构造函数
public MMArrayStack()
{
array = new ArrayList();
}
public MMArrayStack(int capacity)
{
array = new ArrayList(capacity);
}
// 压栈
public void push(T t)
{
array.Add(t);
}
// 出栈
public void pop()
{
if (array.Count > 0)
{
array.RemoveAt(array.Count - 1);
}
}
// 获取栈顶元素
public T peek()
{
if (array.Count > 0)
{
return (T)array[array.Count - 1];
}
else
{
return default(T);
}
}
}
}
2.3 栈的应用举例
例:leetcode 20号题,有效的括号。编码语言:C#。
- 有效括号 C# 栈 解法
解题思路
语言:C#
语法技术:栈
关键字:进栈、出栈、空栈、栈顶
代码
public class Solution {
public bool IsValid(string s)
{
Stack stack = new Stack();
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
if (c == '[' || c == '(' || c == '{')
{
stack.Push(c);
}
else
{
if (stack.Count == 0)
{
return false;
}
if (c == ']' || c == ')' || c == '}')
{
Char top = (Char)stack.Peek();
if (top == '[' && c == ']' ||
top == '(' && c == ')' ||
top == '{' && c == '}')
{
stack.Pop();
}
else
{
return false;
}
}
}
}
return (stack.Count == 0);
}
}
- C# 遍历字符串
方式一
foreach(char c in aStr){
}
方式二
for (int i = 0; i < s.Length; i++) {
char c = s[i];
}
方式三
for (char c : s.toCharArray()) {
}
4. 栈和队列的时间复杂度
5. 讨论
栈和队列的思想还是挺简单的,并且应用场景也比较多,底层的实现可以用链表,或者数组等数据结构来实现栈和队列。在使用高级开发语言时,采用数组来自定义一个栈或者队列还是挺简单的。学习栈和队列,最主要的是理解栈和队列的特性,以及理解数据在栈和队列里的存储。
5.1 栈和数组的区别与联系
栈可以通过数组或者链表来实现,因为栈本身是有序的,数组也是有序的。
一般我们说的栈,不允许能乱”插入“元素,只能栈顶进栈,站顶出栈(当然如果要插入也是可以实现并实行的通的),数组是可以插入元素的。
数组可以通过下标来获取元素,栈只能每次获取到栈首位置的元素,依次出栈。
[参考]
[1] C# 动态数组(ArrayList): https://www.runoob.com/csharp/csharp-arraylist.html
[2] Java编程中ArrayList和LinkedList之间的区别: https://www.sohu.com/a/290684704_445013