第5章栈和队列
栈和队列是两种面向表的数据结构
5.1栈、栈的实现以及Stack类
栈的标准模型是自助餐厅的盘子堆
5.1.1栈的操作
5.1.2Stack类的实现
class CStack
{
private int p_index;
private ArrayList list;
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
{
get
{
return list[p_index];
}
}
}
下面就用这段代码来编写一个用栈解决问题的程序。
判断是否是回文
static void Main(string[] args)
{
CStack alist = new CStack();
string ch;
string word = "sees";
bool isPalindrome = true;
for(int x=0;x<word.Length;x++)
alist.push(word.Substring(x,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 + "is a palindrome.");
else
Console.WriteLine(word + "is not a palindrome.");
Console.Read();
}
5.2 Stack类
Stack类是ICollection接口的一个实现,它代表了一个LIFO群集或一个栈。
5.2.1Stack构造器方法
这里有三种方法来实例化一个栈的对象
Stack myStack = new Stack();
第二种构造方法允许创建一个来自另一个群集对象的栈对象。例如,可以把构造器作为数组进行传递,并且用来自现有数组的元素构建成栈:
String[] names = new string[]{“Raymond”, “David”, “Mike”};
Stack nameStack = new Stack(names);
执行pop方法会首先把“mike”从栈中移除。
Stack myStack = new Stack(25)
5.2.2 主要的栈操作
用栈来计算简单的算术表达式
class class1
{
static void Main(string[] args)
{
Stack nums = new Stack();
Stack ops = new Stack();
string expression = "5 + 10 + 15 + 20";
Calculate(nums, ops, expression);
Console.WriteLine(nums.Pop());
Console.Read();
}
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;
}
}
}
5.2.3 Peek 方法
5.2.4 Clear方法
5.2.5 Contains 方法
5.2.6 CopyTo 方法和ToArray方法
CopyTo方法会把栈内的内容复制到一个数组中。数组必须是Object类型,因为这是所有栈对象的数据类型 Stack myStack = new Stack();
for (int i = 20; i > 0; i--)
{
myStack.Push(i);
}
object[] myArray = new object[myStack.Count];
myStack.CopyTo(myArray, 0);
for (int i = 0; i < 20; i++)
{
Console.WriteLine(myArray[i]);
}
ToArray 方法:myArray = myStack.ToArray();
5.2.7 Stack 类的实例:十进制向多种进制的转换
static void Main(string[] args)
{
MulBase(12, 2);
}
static void MulBase(int n, int b)
{
Stack Digits = new Stack();
do
{
Digits.Push(n % b);
n /= b;
} while (n != 0);
while (Digits.Count > 0)
{
Console.Write(Digits.Pop());
}
}
5.3 队列、Queue类以及Queue类的实现
5.3.2 Queue类的实现
class CQueue
{
private ArrayList pqueue;
public CQueue()
{
pqueue = new ArrayList();
}
public void Enqueue(object item)
{
pqueue.Add(item);
}
public void DeQueue()
{
pqueue.RemoveAt(0);
}
public object Peek()
{
return pqueue[0];
}
public void ClearQueue()
{
pqueue.Clear();
}
public int Count()
{
return pqueue.Count;
}
}
5.3.4用队列排序数据
class Class1
{
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++)
{
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};
for (int i = 0; i < 10; i++)
numQueue[i] = new Queue();
RSort(numQueue, nums, DigitType.ones);
BuildArray(numQueue, nums);
Console.WriteLine();
Console.WriteLine("First pass results");
DisplayArray(nums);
RSort(numQueue, nums, DigitType.tens);
BuildArray(numQueue, nums);
Console.WriteLine();
Console.WriteLine("Second pass results");
DisplayArray(nums);
Console.WriteLine();
}
}
5.3.5 源自Queue类的优先队列
许多应用程序在操作中都利用到了优先队列,一个很好的实例就是在计算机操作系统内的进程处理。优先级为0的进程比优先级为20的任务具有更高的优先性。