数据结构之基本结构 Stack,Queue

来源:互联网 发布:叽叽歪歪是什么软件 编辑:程序博客网 时间:2024/06/07 02:03

开始复习专业课了,慢慢来。


Stack

栈,这种表的特点是先进后出,课本上很形象的一幅图是叠盘子,先放的盘子是最后被取出来的。

栈中元素的插入和删除都是在栈顶进行的,而表的另一端就是栈底。

主要成员函数:push(const stack_entry &num) 将元素num推入栈中,放在栈顶,栈顶指针加一。

                       pop()  将栈顶元素弹出栈,具体实现是通过将栈顶指针减一。

                       top(stack_entry &num) const 将栈顶元素赋值给num,但并不弹出栈。(这里必须用形参,实参是传不回去的。。。)

                       clear() 将栈清空  

                       empty() const 检测栈是否为空,为const类型,不可随意更改

数据成员; stack_entry  entry[n]  在此通过数组来实现栈; 由于声明的数组类型,所以n必须声明为const变量

                  count  栈中元素个数,利用count-1记录栈顶

在栈的实现中,利用泛型将栈用于许多不同的应用中,给起赋予不同的值类型,同时利用枚举变量作为stack类的方法的返回类型,便于返回错误信息。


Queue

队列,这种表的特点是先进先出(first in first out,即FIFO),就像排队买票一样,排在前面的人永远先买到票。

队列有队头和队尾,先进先出则是利用这两个指针实现的,即在队头进行删除操作,在队尾进行插入操作。

主要成员函数:append(queue_entry &num)将元素num推入队列中,放在队尾,队尾指针加1

                       serve()  将队头元素弹出队,将队头指针减一

                       retrieve(queue_entry &num) const 将队头元素赋值给元素num

                       其他函数与stack类似

数据成员:queue_entry entry[n] 在此同样通过数组来实现队列

                count 队列元素个数,通过count是否为0来判断队列是否为空

                front,rear 队头队尾指针

注:

为了减少队列删除元素的复杂度,通常使用循环队列,即删除一个元素时只改变front指针,不移动其后的所有元素,而当队尾指针或者队头指针等于数组容量时则置零,实现循环队列。

循环队列会引起如何判断队列为空的问题,如果使用front和rear指针的位置判断队列为空,则会发现当队列为空和队列为满时,rear指针都在front指针的前一个位置

(队列为满时rear必然在front前一个位置;当队列只有一个元素时,删除该元素,rear指针不变,front指针加1,则出现了与队列为满时的情况)

所以需要一种判断队列是否为空的方法,除了通过count来判断队列中元素个数的方法之外(个人认为最简单)还有很多方法,例如

1. 在队头和队尾中保留一个空位,在队尾出现在队头前两个位置时则判断队列为满

2. 增加一个布尔变量,当加入一个元素使rear指针正好在front指针前一个位置时用来指示队列为满

3. 将front或rear设置为特定的值来表示队列为空或为满的情况(与第二种方法类似)

 

总的来说,stack和queue除了数据处理的方式上有点区别,实现上是类似的,都是基本的数据结构,面试题中也常有利用queue实现stack,或用stack实现queue的方法。

网上通常有两种方法可以实现:

1. 入队时直接压入栈1即可;出队时则将栈1中的元素逐个导入栈2中,栈2中的栈顶便类似于queue的队头,进行插入操作

2. 入队时判断栈1是否为空,若不为空,证明元素在栈1中,则可以进行入队操作,否则将元素先从栈2移入栈1再进行操作;

   同理,出队时则判断栈2是否为空,若不为空,则可以进行出队操作,否则将元素从栈1移入栈2再进行操作。

第二种方法将第一种方法进行了优化,减少了不必要的移动。总的来说,stack和queue是基础啊~~~