数据结构和算法 – 3.堆栈和队列

时间:2020-12-05 14:40:53

1.栈的实现

 

后进先出

 

数据结构和算法 – 3.堆栈和队列

 

自己实现栈的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections; namespace 数据结构和算法
{
//栈
class CStack
{
private ArrayList list;
private int p_index;
public CStack()
{
list = new ArrayList();
p_index = -1;
}
public int count
{
get { return list.Count; }
} public void Push(object item)
{
list.Add(item);
p_index++;
} public object Pop()
{
object obj = list[p_index];
list.RemoveAt(p_index);
p_index--;
return obj;
} public void Clear()
{
list.Clear();
p_index = -1;
}
//查看
public object Peek()
{
return list[p_index];
} static void Main(string[] args)
{
//回文: sees倒过来还是sees
CStack alist = new CStack();
string ch;
string word = "sees";
bool ispalindrome = true;
for (int i = 0; i < word.Length; i++)
{
alist.Push(word.Substring(i, 1));
}
int pos = 0;
while (alist.count > 0)
{
ch = alist.Pop().ToString();
if (ch!=word.Substring(pos,1))
{
ispalindrome = false;
break;
}
pos++;
}
if (ispalindrome)
{
Console.WriteLine(word+" 是回文.");
}
else
{
Console.WriteLine(word + " 不是回文.");
} Console.ReadKey();
}
}
}

数据结构和算法 – 3.堆栈和队列

 


2.Stack类(堆栈)

Stack 类是 ICollection 接口的一个实现。它代表了一个 LIFO 群集或一个堆栈。此类在.NET 框架中是作为循环缓冲来实现的。这使得能动态地分配进栈数据项的空间。

Stack 类包含进栈方法、出栈方法以及取值方法。此外,还有用于确定堆栈内元素数量的方法,清除堆栈全部数值的方法,以及把堆栈数值作为数组返回的方法。

 

CopyTo 方法和 ToArray 方法

CopyTo 方法会把堆栈内的内容复制到一个数组中。数组必须是 Object 类型,因为这是所有堆栈对象的数据类型。此方法会取走两个参数:一个数组和开始放置堆栈元素的数组的起始索引。堆栈内元素按照 LIFO 的顺序进行复制操作,就好像对它们进行出栈操作一样。下面这段代码说明了 CopyTo 方法的调用:

Stack myStack = new Stack();
for (int i = 20; i > 0; i--)
myStack.Push(i);
object[] myArray = new object[myStack.Count];
myStack.CopyTo(myArray, 0);

ToArray 方法的工作原理与 CopyTo 方法类似。但是用户无法指定数组的起始索引位置,而是需要在赋值语句中创建新的数组。实例如下所示:

Stack myStack = new Stack();
for (int i = 0; i > 0; i++)
myStack.Push(i);
object[] myArray = new object[myStack.Count];
myArray = myStack.ToArray();

 

堆栈的实际操作

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; namespace 数据结构和算法
{
class 堆栈的操作
{
static void Main()
{
Stack nums = new Stack();
Stack ops = new Stack();
string expression = "5 + 10 + 15 +20";
Calculate(nums, ops, expression); Console.WriteLine("Pop之前的数据:" + nums.Peek());
nums.Push("1");
Console.WriteLine("Pop的数据:" + nums.Pop());
//nums.Push("1");
Console.WriteLine("Pop之后的数据:" + nums.Peek());
nums.Clear();
if (nums.Count == 0)
{
Console.WriteLine("Clear之后的数据为空");
}
else
Console.WriteLine("Clear之后的数据是否为空" + nums.Peek());
Console.Read();
} //IsNumeric isn'tbuilt into C# so we must define it
static bool IsNumeric(string input)
{
bool flag = true;
string pattern = (@"^\d+$");
Regex validate = new Regex(pattern);
if (!validate.IsMatch(input))
{
flag = false;
}
return flag;
} static void Calculate(Stack N, Stack O, string exp)
{
string ch, token = "";
for (int p = 0; p < exp.Length; p++)
{
ch = exp.Substring(p, 1);
if (IsNumeric(ch))
{
token += ch; //+=
}
if (ch == " " || p == (exp.Length - 1))
{
if (IsNumeric(token))
{
N.Push(token);
token = "";
}
}
else if (ch == "+" || ch == "-" || ch == "*" || ch == "/")
{
O.Push(ch);
}
if (N.Count == 2)
{
Compute(N, O);
}
}
} static void Compute(Stack N, Stack O)
{
int oper1, oper2;
string oper;
oper1 = Convert.ToInt32(N.Pop());
oper2 = Convert.ToInt32(N.Pop());
oper = Convert.ToString(O.Pop());
switch (oper)
{
case "+":
N.Push(oper1 + oper2);
break;
case "-":
N.Push(oper1 - oper2);
break;
case "*":
N.Push(oper1 * oper2);
break;
case "/":
N.Push(oper1 / oper2);
break;
}
}
}
}

数据结构和算法 – 3.堆栈和队列

 

 


3.队列

先进先出

enQueue 排队

deQueue 出队


4.Queue类 (队列)

在对一个新的 Queue 对象实例化的时候,队列默认的容量是 32 个数据项。根据定义,当队列已满时,其容量会双倍增长。这就意味着当队列最初达到满容量时,其新的容量值会变为 64。但是大家可以不用受这些数值的限制。

在实例化对队列时,大家可以指定一个不同的初始容量值。

Queue myQueue = new Queue(100);

这个设置把队列的容量值设为了 100 个数据项。当然,大家也可以改变增长的倍数。增长倍数是传递给构造器的第二个参数,如下所示:

Queue myQueue = new Queue(32, 3);

 

用队列存储数据

基数排序是通过对一组数据进行两遍排序来操作的。在这种情况下,整数的取值范围是从 0 到 99。第一遍是基于个位上的数字进行排序,而第二遍则是基于十位上的数字进行排序。然后,根据这些位置上的每个数字来把每一个数放置在一个箱子内。

假设有下列这些数: 91、 46、 85、 15、 92、 35、 31、 22。

数据结构和算法 – 3.堆栈和队列

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace 数据结构和算法
{
class 用队列存储数据
{
enum DigitType {
//个位
ones = 1,
//十位
tens = 10
} //打印排序后的内容
static void DisplayArray(int[] n)
{
for (int x = 0; x <= n.GetUpperBound(0); x++)
Console.Write(n[x] + " ");
} //排序
static void RSort(Queue[] que, int[] n, DigitType digit)
{
int snum;//下标 for (int x = 0; x <= n.GetUpperBound(0); x++)
{
if (digit == DigitType.ones)
snum = n[x] % 10;
else
snum = n[x] / 10;
que[snum].Enqueue(n[x]);
}
} static void BuildArray(Queue[] que, int[] n)
{
int y = 0;
for (int x = 0; x <= 9; x++)
//que的下标count大于0的时候,替换n
while (que[x].Count > 0)
{
n[y] =
Int32.Parse(que[x].Dequeue().ToString());
y++;
}
} static void Main(string[] args)
{
Queue[] numQueue = new Queue[10];
int[] nums = new int[] { 91, 46, 85, 15, 92, 35, 31, 22 };
int[] random = new Int32[99]; DisplayArray(nums); // Display original list
for (int i = 0; i < 10; i++)
numQueue[i] = new Queue(); RSort(numQueue, nums, DigitType.ones);
//numQueue, nums, 1
BuildArray(numQueue, nums);
Console.WriteLine();
Console.WriteLine("第1次排序: ");
//打印排序后的内容
DisplayArray(nums);
// Second pass sort
RSort(numQueue, nums, DigitType.tens);
BuildArray(numQueue, nums);
Console.WriteLine();
Console.WriteLine("第2次排序结果: ");
//打印排序后的内容
DisplayArray(nums);
Console.WriteLine();
Console.Write("Press enter to quit");
Console.Read();
}
}
}

数据结构和算法 – 3.堆栈和队列

 

数据结构和算法 – 3.堆栈和队列

 


5. Queue 类的优先队列

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace 数据结构和算法
{
public struct pqItem
{
//优先级
public int priority;
public string name;
} public class PQueue : Queue
{
static void Main()
{
PQueue erwait = new PQueue();
pqItem[] erPatient = new pqItem[3];
pqItem nextPatient;
erPatient[0].name = "刘在锡";
erPatient[0].priority = 1;
erPatient[1].name = "李光洙";
erPatient[1].priority = 0;
erPatient[2].name = "金钟国";
erPatient[2].priority = 3; for (int x = 0; x <= erPatient.GetUpperBound(0); x++)
erwait.Enqueue(erPatient[x]); nextPatient = (pqItem)erwait.Dequeue(); Console.WriteLine(nextPatient.name);
Console.Read();
} public PQueue()
{ } //重写出队
public override object Dequeue()
{
object[] items; int min;
items = this.ToArray();
//假设第1个最小
min = ((pqItem)items[0]).priority; for (int x = 1; x <= items.GetUpperBound(0); x++)
if (((pqItem)items[x]).priority < min)
{
min = ((pqItem)items[x]).priority;
} this.Clear(); int x2; for (x2 = 0; x2 <= items.GetUpperBound(0); x2++)
if (((pqItem)items[x2]).priority == min && ((pqItem)items[x2]).name != "")
this.Enqueue(items[x2]); return base.Dequeue();
}
} }

数据结构和算法 – 3.堆栈和队列