C#数据结构中栈和队列的一些心得

1.栈和队列
栈和队列是两种非常重要的数据结构,在软件设计中应用很多。栈和队列也是线性结构,线性表、栈和队列这三种数据结构的数据元素以及数据元素间的逻辑关系完全相同,差别是线性表的操作不受限制,而栈和队列的操作受到限制。栈的操作只能在表的一端进行,队列的插入操作在表的一端进行而其他操作在表的另一端进行,所以,把栈和队列称为操作受限的线性表。
(1)栈
栈(Stack)是操作限定在表的尾端进行的线性表。表尾由于要进行插入、删除等操作,所以它具有特殊的含义,把表尾称为栈顶(Top),另一端是固定的,叫栈底(Bottom)。当栈中没有数据元素时叫空栈(Empty Stack)。
栈通常的记为:S=(a1,a2,...,an),S是英文单词stack的第一个字母。a1为栈底元素,an为栈顶元素。这n个数据元素按照a1,a2,...an的顺序依次入栈,而出栈的次序相反,an第一个出栈,a1最后一个出栈。所以,栈的操作是按照后进先出(Last In First Out,简称LIFO)或先进后出(First In Last Out,简称FILO)的原则进行的,因此,栈又称为LIFO表或FILO表
BCL中的栈
C#2.0以下版本只提供了非泛型的Stack类(存储object类型)
C#2.0提供了泛型的Stack<T>类
重要的方法如下
[1]Push()入栈(添加数据)
[2]Pop()出栈(删除数据,返回被删除的数据)
[3]Peek()取得栈顶的数据,不删除
[4]Clear()清空所有数据
属性->[5]Count取得栈中所有数据的个数
实例:
//使用BCL中的Stack<T>类
Stack<char> stack = new Stack<char>();
stack.Push('a');
stack.Push('b');
stack.Push('c');//栈顶数据
Console.WriteLine("push a b c之后的数据个数:"+stack.Count);
char temp = stack.Pop();//取得栈顶的数据,并把栈顶的数据删除
Console.WriteLine("pop之后得到的数据是:"+temp);
Console.WriteLine("pop之后栈中数据的个数:"+stack.Count);
char temp2 = stack.Peek();//取得栈顶的数据,不删除
Console.WriteLine("peek之后得到的数据是:"+temp2);
Console.WriteLine("peek之后栈中的数据个数:"+stack.Count);
stack.Clear();
Console.WriteLine("clear之后栈中数据的个数:"+stack.Count);
Console.WriteLine("空栈的时候,取得栈顶的值为:"+stack.Peek());//会出现异常(堆栈为空)
//当空栈时不要进行Peek和Pop操作
*顺序栈
用一片连续的存储空间来存储栈中的数据元素(使用数组),这样的栈称为顺序栈(Sequence Stack)。类似于顺序表,用一维数组来存放顺序栈中的数据元素。栈顶指示器top设在数组下标为0的端,top随着插入和删除而变化,当栈为空时,top=-1.
*链栈
栈的另外一种存储方式是链式存储,这样的栈称为链栈(Linked Stack)。链栈通常用单链表来表示,它的实现是单链表的简化。所以,链栈结点的结构与单链表结点的结构一样。由于链栈的操作只是在一端进行,为了操作方便,把栈顶设在链表的头部,并且不需要头结点。
把链栈看做一个泛型类,类名为LinkStack<T>。LinkStack<T>类中有一个字段top表示栈顶指示器。由于栈只能访问栈顶的数据元素,而链栈的栈顶指示器又不能指示栈的数据元素的个数。所以,求链栈的长度时,必须把栈中的数据元素一个个出栈,每出栈一个数据元素,计数器就增加1,但这样会破坏栈的结构。为保留栈中的数据元素,需把出栈的数据元素先压入另外一个栈,计算完长度后,再把数据元素压入原来的栈。但这种算法的空间复杂度和时间复杂度都很高,所以,以上两种算法都不是理想的解决办法。理想的解决办法是LinkStack<T>增设一个字段表示链栈中结点的个数。
(2)队列
队列(Queue)是插入操作限定在表的尾部而其他操作限定在表的头部进行的线性表。把进行插入操作的表尾称为队尾(Rear),把进行其他操作的头部称为队头(Front)。当队列中没有数据元素时称为空队列(Empty Queue)。
队列通常记为:Q=(a1,a2,a3...an),Q是英文单词Queue的第一个字母。a1为队头元素,an为队尾元素。这n个元素是按照a1,a2,...an的次序依次入队的,出队的次序与入队的相同,a1第一个出队,an最后一个出队。所以,队列的操作是按照先进先出(First In First Out)或后进后出(Last In Last Out)的原则进行的,因此,队列又称为FIFO表或LILO表。
在实际生活中有许多类似于队列的例子。比如,排队取钱,先来的先取,后来的排在队尾。队列的操作是线性表操作的一个子集。队列的操作主要包括在队尾插入元素、在队头删除元素、取队头的元素和判断队列是否为空等。与栈一样,队列的运算是定义在逻辑结构层次上的,而运算的具体实现是建立在物理内存结构层次上的。因此,把队列的操作成为逻辑结构的一部分,每个操作的具体实现只有在确定了队列的存储结构之后才能完成。队列的基本运算不是他的全部运算,而是一些常用的基本运算
BCL中的队列
C#2.0以下版本提供了非泛型的Queue类
C#2.0提供了泛型Queue<T>类
常用方法:
[1]Enqueue()入队(放在队尾)
[2]Dequeue()出队(移除队头元素,并返回被移除的元素)
[3]Peek()取得队头的元素,不移除
[4]Clear()清空元素
属性->[5]Count获取队列容量大小
实例:
//使用BCL中的队列
Queue<int> queue = new Queue<int>();
//入队(添加数据)
queue.Enqueue(23);//队头
queue.Enqueue(45);
queue.Enqueue(67);
queue.Enqueue(89);//队尾
Console.WriteLine("添加了23 45 67 89之后队列的大小为:"+queue.Count);
//出队(取得队头的数据,并删除)
int i = queue.Dequeue();
Console.WriteLine("取得队头的数据为:"+i);
Console.WriteLine("出队之后,队列的大小为:"+queue.Count);
int j = queue.Peek();//取得队头的数据,不删除
Console.WriteLine("Peek得到的结果是:"+j);
Console.WriteLine("Peek之后队列的大小为:"+queue.Count);
queue.Clear();
Console.WriteLine("clear之后队列的大小为:"+queue.Count);
*顺序队列
用一片连续的存储空间来存储队列中的数据元素,这样的队列称为顺序队列(Sequence Queue)。类似于顺序栈,用一维数组来存放顺序队列中的数据元素。队头位置设在数组下标为0的端,用front表示,队尾位置设在数组的另一端,用rear表示。front和rear随着插入和删除而变化。当队列为空时,front=rear=-1。
假溢出示例:
null    null    null    null    a5    a6    a7
                            front                 rear
front=3 rear=4-->循环顺序队列
如果再有一个数据元素入队就会出现溢出。但事实上队列中并未满,还有空闲空间,把这种现象叫做假溢出。这是由于队列“队尾入队头出”的操作原则造成的。解决假溢出的方法是将顺序队列看成是首尾相接的循环结构,头尾指示器的关系不变,这种队列叫循环顺序队列(Circular Sequence Queue)。
把顺序队列看做是一个泛型类,类名叫CSeqStack<T>,C是英文单词circular的第一个字母CSeqStack<T>类实现了接口IQueue<T>。用数组来存储循环顺序队列中的元素,在CSeqStack<T>类中用字段data来表示。用字段maxsize表示循环顺序队列的容量,maxsize的值可以根据实际需要进行修改,这通过CSeqStack<T>类的构造器中的参数size来实现,循环顺序队列中的元素由data[0]开始一次顺序存放。字段front表示队头,front的范围是0到maxsize-1.字段rear表示队尾,rear的范围也是0到maxsize-1.如果循环队列为空,front=rear=-1。当执行入队操作时需要判断循环顺序队列是否已满,如果循环顺序队列已满,(rear+1)%maxsize==front,循环顺序队列已满不能插入元素。所以,CSeqStack<T>类除了要实现接口IQueue<T>中的方法外,还需要实现判断循环队列是否已满的成员方法。
*链队列
队列的另外一种存储方式是链式存储,这样的队列称为链队列(Linked Queue)。同链栈一样,链队列通常用单链表来表示,它的实现是单链表的简化。所
以,链队列的结点与单链表的一样。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值