在数据结构中,有些简单的线性结构是非常常用的,比如说堆栈可以用于实现函数的调用,队列可以处理一些需要排队的问题,下面就简单介绍一下这两种数据结构。
一:堆栈
堆栈是一种特殊的数据结构,特点是FILO(First In, Last Out),而且处理的元素也只可以在栈顶这一端。下面给出堆栈常用接口,例如进栈出栈,查看栈顶元素等。
#ifndef STACK_H
#define STACK_H
#include<iostream>
#include<iomanip>
using namespace std;
template<typename Elem>
class Stack{
private:
//栈的大小,默认为10
int maxSize;
//栈顶元素对应下标
int top;
//存储栈元素的数组
Elem * stackArray;
public:
Stack(int size = 10){
maxSize = size;
top = maxSize;
stackArray = new Elem[maxSize];
}
~Stack(){
delete[] stackArray;
}
//进栈操作
bool push(const Elem & e){
if (top > 0){
stackArray[--top] = e;
return true;
}
else{
cout << "Error: stack overflow!!!" << endl;
return false;
}
}
//出栈操作
bool pop(Elem & popValue){
if (top < maxSize){
popValue = stackArray[top++];
return true;
}
else{
cout << "Error: stack is empty!!!" << endl;
return false;
}
}
//打印栈元素
void show() const{
cout << setw(12) << "Stack top:";
for (int i = top, count = 0; i < maxSize; ++i){
cout << setw(6) << stackArray[i];
if (++count % 10 == 0)
cout << endl;
}
cout << endl;
}
//返回栈顶元素的值
Elem getTopValue(){
if (top == maxSize){
cout << "Error: stack is empty, getTopValue() failed!!!" << endl;
return 0;
}
else{
return stackArray[top];
}
}
//判断栈是否为空
bool isEmpty() const{
return top == maxSize;
}
//判断栈是否已满
bool isFull() const{
return top == 0;
}
};
#endif
栈还有基于链表的实现,此处不再具体给出,具体的实现方法和基于数组的栈实现方法大同小异。
二:队列
还有一种特殊的数据结构叫做队列,现实生活中也经常有这种情况,队列的特点FIFO(FIrst In, First Out),而且只可以在队尾插入元素,元素只可以在队首出来。队列有些比较常用的操作,比如进队出队,队列的首尾元素叫法也不一样(队首是front,队尾是rear)。基于数组的队列主要采取循环队列的实现方法,下面简单介绍循环队列的实现过程。
循环队列如下
下面是循环队列基于数组的实现
#include<iostream>
#include<iomanip>
using namespace std;
template<typename Elem>
class Queue{
private:
//队列的最大元素个数
int maxSize;
//队列当前的元素个数
int currentSize;
//队首元素下标
int front;
//对尾元素下标
int rear;
//储存堆元素的数组
Elem * queueArray;
public:
Queue(int size = 10){
//队列的最大元素个数
maxSize = size;
//队列里的实际元素个数
currentSize = 0;
//存储队列元素的数组
queueArray = new Elem[maxSize];
//队首元素的对应下标
front = 0;
//队尾元素对应的下标
//当插入第一个元素时front与rear均为0,故此处初始化为-1
rear = -1;
}
~Queue(){
delete[] queueArray;
}
//在队尾插入元素
bool enqueue(const Elem & e){
//当数组中的实际元素个数大于等于最大元素个数时
if (currentSize == maxSize){
cout << "Error: Queue overflow while enqueuing element " << e << endl;
return false;
}
else{
//当rear指向queueArray最后一个元素时,rear回到-1位置
if (rear + 1 == maxSize)
rear -= maxSize;
//在rear指向的最后一个元素后面插入一个元素
queueArray[++rear] = e;
currentSize++;
return true;
}
}
//在队首执行出对操作,并把出队元素值保存在dequeueValue
bool dequeue(Elem & dequeueValue){
//当队列中没有元素时
if (currentSize == 0){
cout << "Error: Queue is empty!!!" << endl;
return false;
}
else{
//当front指向queueArray最后一个元素时
if (front + 1 >= maxSize)
front -= maxSize;
++front;
--currentSize;
return true;
}
}
//判断队列是否为空
bool isEmpty() const{
return currentSize == 0;
}
//判断队列是否已满
bool isFull() const{
return currentSize == maxSize;
}
//打印队列
void show() const{
cout << "最大元素个数:" << maxSize << " 当前元素个数:" << currentSize << endl;
cout << "队首下标:" << setw(4) << front << " 队尾下标:" << setw(4) << rear << endl;
cout << "front: ";
for (int i = front, j = 1; j <= currentSize; ++j, ++i){
if (i >= maxSize)
i -= maxSize;
cout << setw(6) << queueArray[i];
}
cout << endl;
}
};
三:总结
线性表、栈与队列的异同点:
不同点:
① 运算规则不同,线性表为随机存取,而栈是只允许在一端进行插入和删除运算,因而是后进先出表LIFO;队列是只允许在一端进行插入、另一端进行删除运算,因而是先进先出表FIFO。
② 用途不同,线性表比较通用;堆栈用于函数调用、递归和简化设计等;队列用于离散事件模拟、多道作业处理和简化设计等。