堆栈是限定在表尾进行插入或删除操作的线性表,System.Stack表示对象的简单的后进先出非泛型集合。对堆栈的主要操作包括:元素入栈、元素出栈、清空堆栈、判断堆栈是否为空、获取堆栈元素个数。
下面的程序代码中的函数ShowStackOperation()演示了上述介绍的堆栈五种常用操作。
private void ShowStackOperation()
{
Stack s = new Stack(); ///创建一个堆栈s
s.Push("Hello word."); ///元素"Hello word."入栈
s.Push(1); ///元素入栈
s.Pop(); ///元素出栈
int stackCount = s.Count; ///获取堆栈的元素个数
bool isEmpty = s.Count > 0 ? false : true; ///判断堆栈是否为空
s.Clear(); ///清空堆栈的所有元素
}
在下述程序代码中,笔者创建了一个类StackRealizeQueue。该类使用两个堆栈实现一个队列(一种先进先出的线性表)。并实现队列的常用操作,如元素入队、元素出队、清空队列、判断队列是否为空、获取队列元素个数等。
类StackRealizeQueue的构造函数初始化两个堆栈。其中fStack堆栈存放队列的值,sStack为备用堆栈,在队列出队时使用。清空队列、判断队列是否为空、获取队列元素个数的操作实现都比较简单,程序代码如下:
/// <summary>
/// 使用两个堆栈实现一个队列
/// </summary>
public class StackRealizeQueue
{
/// <summary>
/// fStack堆栈存放队列的值
/// </summary>
Stack fStack;
/// <summary>
/// 备用堆栈,在队列出队时使用
/// </summary>
Stack sStack;
/// <summary>
/// 构造函数,初始化fStack和sStack
/// </summary>
public StackRealizeQueue()
{
fStack = new Stack();
sStack = new Stack();
}
/// <summary>
/// 清空队列
/// </summary>
public void Crear()
{
fStack.Clear();
}
/// <summary>
/// 获取队列的长度
/// </summary>
public int Length
{
get{return fStack.Count;}
}
/// <summary>
/// 判断队列是否为空
/// </summary>
public bool IsEmpty()
{
return (fStack.Count <= 0 && sStack.Count <= 0);
}
下面分析两个堆栈实现一个队列的原理,设队列入队的元素依次为“1,2,3,4,5,6,7,8,9,10”,那么元素出队的顺序也是“1,2,3,4,5,6,7,8,9,10”。
当 元素“1,2,3,4,5,6,7,8,9,10”全部入栈到fStack中时,它的排列顺序原来与排序顺序的相反,即为“10,9,8,7,6,5, 4,3,2,1”。此时sStack堆栈为空,如图2.26所示。为了让元素“1”出队,此时,可以依次把元素“10,9,8,7,6,5,4,3,2, 1”从fStack堆栈中弹出,并压入堆栈sStack中,如图2.27所示。然后元素“1”出队,此时,可以依次把元素“10,9,8,7,6,5, 4,3,2”从sStack堆栈中弹出,并压入堆栈fStack中,如图2.28所示。
图2.26 元素入队 图2.27 元素“1”准备出队 图2.28 元素“1”出队之后
根据上面的分析,可以定义队列的入队和出队操作。当元素入队时,由于队列的元素仅仅存放在堆栈fStack中,因此只要把入队的元素入栈到堆栈fStack中即可。队列入队操作的程序代码如下:
/// <summary>
/// 元素入队
/// </summary>
public void EnQueue(object oValue)
{
fStack.Push(oValue);
}
当 元素出队时,由于队列的元素仅仅存放在堆栈fStack中。首先把堆栈fStack中的元素全部弹出,并压入到堆栈sStack中;然后堆栈sStack 最上面一个元素出栈,并输出此元素;最后又重新把sStack堆栈的所有元素重新压入到fStack堆栈中,从而完成了队列出队的操作。队列出队操作的程 序代码如下:
/// <summary>
/// 元素出队
/// </summary>
public object DeQueue()
{
if(IsEmpty() == true){return null;}
if(sStack.Count > 0){return null;}
///把fStack堆栈的所有元素压入到sStack堆栈中
while(fStack.Count > 0)
{
sStack.Push(fStack.Pop());
}
object oTemp = sStack.Pop(); ///获取sStack堆栈的最上面的元素
///把sStack堆栈的所有元素重新压入到fStack堆栈中
while(sStack.Count > 0)
{
fStack.Push(sStack.Pop());
}
return oTemp;
}
}
应 用程序Sample_02_06的StackPage.aspx页面中的函数Page_Load(object sender, EventArgs e)首先调用函数TestStackRealizeQueue()创建一个队列queue,并向队列中添加四个元素,它们依次是“true”、“$”、 “34567”和“Hello Word”,然后打印队列中的所有元素。函数Page_Load(object sender, EventArgs e)的程序代码如下:
protected void Page_Load(object sender, EventArgs e)
{
TestStackRealizeQueue();Response.End();
}
private void TestStackRealizeQueue()
{ ///创建一个队列
StackRealizeQueue queue = new StackRealizeQueue();
queue.Crear();
bool b = true;
char c = '$';
int i = 34567;
string s = "Hello Word";
///入队
queue.EnQueue(b);
queue.EnQueue(c);
queue.EnQueue(i);
queue.EnQueue(s);
///打印队列的所有元素
while(queue.IsEmpty() == false)
{
Response.Write(queue.DeQueue().ToString() + "<br>");
}
}
把StackPage.aspx设为应用程序Sample_02_06的起始页面,并运行应用程序,StackPage.aspx页面如图2.29所示。
图2.29 StackPage.aspx页面显示双堆栈的操作结果
下面的程序代码中的函数ShowStackOperation()演示了上述介绍的堆栈五种常用操作。
private void ShowStackOperation()
{
Stack s = new Stack(); ///创建一个堆栈s
s.Push("Hello word."); ///元素"Hello word."入栈
s.Push(1); ///元素入栈
s.Pop(); ///元素出栈
int stackCount = s.Count; ///获取堆栈的元素个数
bool isEmpty = s.Count > 0 ? false : true; ///判断堆栈是否为空
s.Clear(); ///清空堆栈的所有元素
}
在下述程序代码中,笔者创建了一个类StackRealizeQueue。该类使用两个堆栈实现一个队列(一种先进先出的线性表)。并实现队列的常用操作,如元素入队、元素出队、清空队列、判断队列是否为空、获取队列元素个数等。
类StackRealizeQueue的构造函数初始化两个堆栈。其中fStack堆栈存放队列的值,sStack为备用堆栈,在队列出队时使用。清空队列、判断队列是否为空、获取队列元素个数的操作实现都比较简单,程序代码如下:
/// <summary>
/// 使用两个堆栈实现一个队列
/// </summary>
public class StackRealizeQueue
{
/// <summary>
/// fStack堆栈存放队列的值
/// </summary>
Stack fStack;
/// <summary>
/// 备用堆栈,在队列出队时使用
/// </summary>
Stack sStack;
/// <summary>
/// 构造函数,初始化fStack和sStack
/// </summary>
public StackRealizeQueue()
{
fStack = new Stack();
sStack = new Stack();
}
/// <summary>
/// 清空队列
/// </summary>
public void Crear()
{
fStack.Clear();
}
/// <summary>
/// 获取队列的长度
/// </summary>
public int Length
{
get{return fStack.Count;}
}
/// <summary>
/// 判断队列是否为空
/// </summary>
public bool IsEmpty()
{
return (fStack.Count <= 0 && sStack.Count <= 0);
}
下面分析两个堆栈实现一个队列的原理,设队列入队的元素依次为“1,2,3,4,5,6,7,8,9,10”,那么元素出队的顺序也是“1,2,3,4,5,6,7,8,9,10”。
当 元素“1,2,3,4,5,6,7,8,9,10”全部入栈到fStack中时,它的排列顺序原来与排序顺序的相反,即为“10,9,8,7,6,5, 4,3,2,1”。此时sStack堆栈为空,如图2.26所示。为了让元素“1”出队,此时,可以依次把元素“10,9,8,7,6,5,4,3,2, 1”从fStack堆栈中弹出,并压入堆栈sStack中,如图2.27所示。然后元素“1”出队,此时,可以依次把元素“10,9,8,7,6,5, 4,3,2”从sStack堆栈中弹出,并压入堆栈fStack中,如图2.28所示。
图2.26 元素入队 图2.27 元素“1”准备出队 图2.28 元素“1”出队之后
根据上面的分析,可以定义队列的入队和出队操作。当元素入队时,由于队列的元素仅仅存放在堆栈fStack中,因此只要把入队的元素入栈到堆栈fStack中即可。队列入队操作的程序代码如下:
/// <summary>
/// 元素入队
/// </summary>
public void EnQueue(object oValue)
{
fStack.Push(oValue);
}
当 元素出队时,由于队列的元素仅仅存放在堆栈fStack中。首先把堆栈fStack中的元素全部弹出,并压入到堆栈sStack中;然后堆栈sStack 最上面一个元素出栈,并输出此元素;最后又重新把sStack堆栈的所有元素重新压入到fStack堆栈中,从而完成了队列出队的操作。队列出队操作的程 序代码如下:
/// <summary>
/// 元素出队
/// </summary>
public object DeQueue()
{
if(IsEmpty() == true){return null;}
if(sStack.Count > 0){return null;}
///把fStack堆栈的所有元素压入到sStack堆栈中
while(fStack.Count > 0)
{
sStack.Push(fStack.Pop());
}
object oTemp = sStack.Pop(); ///获取sStack堆栈的最上面的元素
///把sStack堆栈的所有元素重新压入到fStack堆栈中
while(sStack.Count > 0)
{
fStack.Push(sStack.Pop());
}
return oTemp;
}
}
应 用程序Sample_02_06的StackPage.aspx页面中的函数Page_Load(object sender, EventArgs e)首先调用函数TestStackRealizeQueue()创建一个队列queue,并向队列中添加四个元素,它们依次是“true”、“$”、 “34567”和“Hello Word”,然后打印队列中的所有元素。函数Page_Load(object sender, EventArgs e)的程序代码如下:
protected void Page_Load(object sender, EventArgs e)
{
TestStackRealizeQueue();Response.End();
}
private void TestStackRealizeQueue()
{ ///创建一个队列
StackRealizeQueue queue = new StackRealizeQueue();
queue.Crear();
bool b = true;
char c = '$';
int i = 34567;
string s = "Hello Word";
///入队
queue.EnQueue(b);
queue.EnQueue(c);
queue.EnQueue(i);
queue.EnQueue(s);
///打印队列的所有元素
while(queue.IsEmpty() == false)
{
Response.Write(queue.DeQueue().ToString() + "<br>");
}
}
把StackPage.aspx设为应用程序Sample_02_06的起始页面,并运行应用程序,StackPage.aspx页面如图2.29所示。
图2.29 StackPage.aspx页面显示双堆栈的操作结果