C#使用双堆栈创建队列

 

堆栈是限定在表尾进行插入或删除操作的线性表,System.Stack表示对象的简单的后进先出非泛型集合。对堆栈的主要操作包括:元素入栈、元素出栈、清空堆栈、判断堆栈是否为空、获取堆栈元素个数。
下面的程序代码中的函数ShowStackOperation()演示了上述介绍的堆栈五种常用操作。
  1. private void ShowStackOperation()
  2. {
  3. Stack s = new Stack();                            ///创建一个堆栈s
  4. s.Push("Hello word.");                            ///元素"Hello word."入栈
  5. s.Push(1);                                          ///元素入栈
  6. s.Pop();                                            ///元素出栈
  7. int stackCount = s.Count;                        ///获取堆栈的元素个数
  8. bool isEmpty = s.Count > 0 ? false : true;    ///判断堆栈是否为空
  9. s.Clear();                                          ///清空堆栈的所有元素
  10. }
在下述程序代码中,笔者创建了一个类StackRealizeQueue。该类使用两个堆栈实现一个队列(一种先进先出的线性表)。并实现队列的常用操作,如元素入队、元素出队、清空队列、判断队列是否为空、获取队列元素个数等。
类StackRealizeQueue的构造函数初始化两个堆栈。其中fStack堆栈存放队列的值,sStack为备用堆栈,在队列出队时使用。清空队列、判断队列是否为空、获取队列元素个数的操作实现都比较简单,程序代码如下:
  1. /// <summary>
  2. /// 使用两个堆栈实现一个队列
  3. /// </summary>
  4. public class StackRealizeQueue
  5. {
  6. /// <summary>
  7. /// fStack堆栈存放队列的值
  8. /// </summary>
  9. Stack fStack;
  10. /// <summary>
  11. /// 备用堆栈,在队列出队时使用
  12. /// </summary>
  13. Stack sStack;
  14. /// <summary>
  15. /// 构造函数,初始化fStack和sStack
  16. /// </summary>
  17. public StackRealizeQueue()
  18. {
  19. fStack = new Stack();
  20. sStack = new Stack();
  21. }
  22. /// <summary>
  23. /// 清空队列
  24. /// </summary>
  25. public void Crear()
  26. {
  27. fStack.Clear();
  28. }
  29. /// <summary>
  30. /// 获取队列的长度
  31. /// </summary>
  32. public int Length
  33. {
  34. get{return fStack.Count;}
  35. }
  36. /// <summary>
  37. /// 判断队列是否为空
  38. /// </summary>
  39. public bool IsEmpty()
  40. {
  41. return (fStack.Count <= 0 && sStack.Count <= 0);
  42. }
下面分析两个堆栈实现一个队列的原理,设队列入队的元素依次为“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中即可。队列入队操作的程序代码如下:
  1. /// <summary>
  2. /// 元素入队
  3. /// </summary>
  4. public void EnQueue(object oValue)
  5. {
  6. fStack.Push(oValue);
  7. }
当元素出队时,由于队列的元素仅仅存放在堆栈fStack中。首先把堆栈fStack中的元素全部弹出,并压入到堆栈sStack中;然后堆栈sStack最上面一个元素出栈,并输出此元素;最后又重新把sStack堆栈的所有元素重新压入到fStack堆栈中,从而完成了队列出队的操作。队列出队操作的程序代码如下:
  1. /// <summary>
  2. /// 元素出队
  3. /// </summary>
  4. public object DeQueue()
  5. {
  6. if(IsEmpty() == true){return null;}
  7. if(sStack.Count > 0){return null;}
  8. ///把fStack堆栈的所有元素压入到sStack堆栈中
  9. while(fStack.Count > 0)
  10. {
  11. sStack.Push(fStack.Pop());
  12. }
  13. object oTemp = sStack.Pop();    ///获取sStack堆栈的最上面的元素
  14. ///把sStack堆栈的所有元素重新压入到fStack堆栈中
  15. while(sStack.Count > 0)
  16. {
  17. fStack.Push(sStack.Pop());
  18. }
  19. return oTemp;
  20. }
  21. }
应用程序Sample_02_06的StackPage.aspx页面中的函数Page_Load(object sender, EventArgs e)首先调用函数TestStackRealizeQueue()创建一个队列queue,并向队列中添加四个元素,它们依次是“true”、“$”、“34567”和“Hello Word”,然后打印队列中的所有元素。函数Page_Load(object sender, EventArgs e)的程序代码如下:
  1. protected void Page_Load(object sender, EventArgs e)
  2. {
  3. TestStackRealizeQueue();Response.End();
  4. }
  5. private void TestStackRealizeQueue()
  6. {  ///创建一个队列
  7. StackRealizeQueue queue = new StackRealizeQueue();
  8. queue.Crear();
  9. bool b = true;
  10. char c = '$'
  11. int i = 34567; 
  12. string s = "Hello Word";
  13. ///入队
  14. queue.EnQueue(b);
  15. queue.EnQueue(c);
  16. queue.EnQueue(i);
  17. queue.EnQueue(s);
  18. ///打印队列的所有元素
  19. while(queue.IsEmpty() == false)
  20. {
  21. Response.Write(queue.DeQueue().ToString() + "<br>");
  22. }
  23. }
把StackPage.aspx设为应用程序Sample_02_06的起始页面,并运行应用程序,StackPage.aspx页面如图2.29所示。

图2.29  StackPage.aspx页面显示双堆栈的操作结果

摘自人邮的《ASP.net 2.0编程指南》。
网址是: http://www.china-pub.com/computers/common/info.asp?id=35207
http://www.huachu.com.cn/itbook/itbookinfo.asp?lbbh=10061253
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值