栈和队列的区别(含栈和队列的封装实现)

栈:

栈是一种操作受限的线性表只允许从一端插入和删除数据。栈有两种存储方式,即线性存储(顺序栈)和链表存储(链栈)。栈的一个最重要的特征就是栈的插入和删除只能在栈顶进行,所以每次删除的元素都是最后进栈的元素,故栈也被称为后进先出(LIFO)表。每个栈都有一个栈顶指针,它初始值为-1,且总是指向最后一个入栈的元素,栈有两种处理方式,即进栈(push)和出栈(pop),因为在进栈只需要移动一个变量存储空间,所以它的时间复杂度为O(1),但是对于出栈分两种情况,栈未满时,时间复杂度也为O(1),但是当栈满时,需要重新分配内存,并移动栈内所有数据,所以此时的时间复杂度为O(n)。以下举例栈结构的两种实现方式,线性存储和链接存储。
在这里插入图片描述

1. 顺序栈的实现

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

template<class datatype>
class StackList
{
private:
	datatype *base;//栈底指针
	datatype *top;//栈顶指针
	int maxsize;//最大容量
	int len;//栈元素个数
public:
	StackList();//不带参数的构造函数
	StackList(int n);//初始化最大容量为n的构造函数
	~StackList();//析构函数
	void push(datatype value);//入栈
	void pop();//出栈
	datatype gettop();//获取栈顶元素
	datatype getbase();//获取栈底元素
	bool isequal(const StackList & A);//判断两个栈是否相等
	friend ostream &operator<<(ostream &output, const StackList &D)
	{
		if (D.len == 0)
		{
			cout << "stack is empty" << endl;
		}
		else
		{
			datatype *p = D.base;
			for (int i = 0; i < D.len; i++)
			{
				output << *p << " ";
				p++;
			}
			cout << endl;
		}
		return output;
	}
};

//不带参数的构造函数
template<class datatype>
StackList<datatype>::StackList()
{
	len = 0;
	maxsize = 10;
	base = new datatype[maxsize];
	if (!base)
		cerr << "存储分配失败" << endl;
	top = base;
}

//初始化最大容量为n的构造函数
template<class datatype>
StackList<datatype>::StackList(int n)
{
	len = 0;
	maxsize = n;
	base = new datatype[maxsize];
	if (!base)
		cerr << "存储分配失败" << endl;
	top = base;
}

//析构函数
template<class datatype>
StackList<datatype>::~StackList()
{
	delete base;
}

//入栈
template<class datatype>
void StackList<datatype>::push(datatype value)
{
	if (top - base == maxsize)
		cerr << "存储空间已满" << endl;
	else
	{
		*top++ = value;
		len++;
	}
}

//出栈
template<class datatype>
void StackList<datatype>::pop()
{
	if (base == top)
		cerr << "stack is empty ,can't pop" << endl;
	else
	{
		top--;
		len--;
	}
}

//获取栈顶元素
template<class datatype>
datatype StackList<datatype>::gettop()
{
	return *(top - 1);
}

//获取栈底元素
template<class datatype>
datatype StackList<datatype>::getbase()
{
	return *base;
}

//判断两个栈是否相等
template<class datatype>
bool StackList<datatype>::isequal(const StackList & A)
{
	if (len != A.len)
		return false;
	else
	{
		datatype *q = base;
		datatype *k = A.base;
		for (int i = 0; i < len; i++)
		{
			if (*q != *k)
				return false;
			else
			{
				q++;
				k++;
			}
		}
		return true;
	}
}

int main()
{
	//测试
	StackList<int> A;
	StackList<int> B(5);
	A.push(1);
	A.push(2);
	cout << A;
	A.pop();
	A.push(3);
	cout << A;
	cout << A.gettop() << endl;
	cout << A.getbase() << endl;
	cout << A.isequal(B) << endl;
	system("pause");
	return 0;
}

2. 链栈的实现:

#include<iostream>
using namespace std;
template<class datatype>
class LinkStack;

template<class datatype>
class node
{
public:
	friend class LinkStack<datatype>;
	datatype val;
	node<datatype> *next;
	node(datatype x) : val(x), next(NULL) {};
};

template<class datatype>
class LinkStack
{
private:
	node<datatype> *S;
	int len;
public:
	LinkStack();
	LinkStack(datatype a[],int n);//将数组a的前n个元素压入栈
	~LinkStack();
	void push(datatype value);//入栈
	void pop();//出栈
	datatype top();//获取栈顶元素
	bool empty1();//判空
	bool empty2();//判空
	friend ostream &operator<<(ostream &output, const LinkStack &D)
	{
		if (D.len==0)
		{
			cout << "LinkStack is empty" << endl;
		}
		else
		{
			node<datatype> *p = D.S;
			for (int i = 0; i < D.len; i++)
			{
				cout << p->val << " ";
				p = p->next;
			}
			cout << endl;
		}
		return output;
	}
};

template<class datatype>
LinkStack<datatype>::LinkStack()
{
	S = NULL;
	len = 0;
}

template<class datatype>
LinkStack<datatype>::LinkStack(datatype a[],int n)
{
	S = NULL;
	int i = 0;
	for (; i < n; i++)
	{
		if (a[i] != 0)
			push(a[i]);
		else break;
	}
	len = i ;
}

template<class datatype>
LinkStack<datatype>::~LinkStack()
{
	if (len != 0)
	{
		node<datatype> *p = S,*k;
		for (int i = 0; i < len; i++)
		{
			k = p->next;
			delete p;
			p = k;
		}
	}
}

template<class datatype>
void LinkStack<datatype>::push(datatype value)
{
	node<datatype> *p=S;
	S = new node<datatype>(value);
	S->next = p;
	len++;
}

template<class datatype>
void LinkStack<datatype>::pop()
{
	node<datatype> *p = S;
	S = S->next;
	len--;
	delete p;
}

template<class datatype>
datatype LinkStack<datatype>::top()
{
	return S->val;
}

template<class datatype>
bool LinkStack<datatype>::empty1()
{
	return !len;
}

template<class datatype>
bool LinkStack<datatype>::empty2()
{
	if (S == NULL)
		return true;
	else return false;
}
int main()
{
	//测试
	int a[10] = { 1,3,4,2 };
	LinkStack<int> A;
	LinkStack<int> B(a,5);
	cout << B;
	//cout << A.empty1() << " " <<A.empty2() << endl;
	A.push(1);
	//cout << A.empty1() << " " << A.empty2() << endl;
	A.push(2);
	cout << A;
	A.pop();
	cout << A;
	cout << A.top()<<endl;
	system("pause");
	return 0;
}

队列:

队列以一种先入先出(FIFO)的线性表,教科书上有明确的定义与描述。类似于现实中排队时的队列(队尾进,队头出),队列只在线性表两端进行操作,插入元素的一端称为表尾,删除(取出)元素的一端称为表头。分别对应于入队和出队操作。队列有两种存储方式,即线性存储(循环队列)和链表存储(链队)
在这里插入图片描述

1. 循环队列的实现:

#include<iostream>
using namespace std;

//弃用一个空间的循环队列,防止假溢出
template<class datatype>
class Cirqueue
{
private:
	int front;
	int rear;
	datatype *base;
	int maxsize;
public:
	Cirqueue();
	Cirqueue(int max);
	~Cirqueue();
	bool empty();
	bool full();
	int getlength();
	void enqueue(datatype value);
	void dequeue();
	datatype getfront();
	datatype getrear();
	friend ostream &operator<<(ostream &output, Cirqueue& D)
	{
		if (D.empty())
			cout << "队列为空" << endl;
		else
		{
			int p = D.front;
			for (int i = 0; i < D.getlength(); i++)
			{
				output << D.base[p] << " ";
				p = (p + 1) % D.maxsize;
			}
			cout << endl;
		}
		return output;
	}
};

template<class datatype>
Cirqueue<datatype>::Cirqueue()
{
	maxsize = 11;
	base = new datatype[maxsize];
	front = rear =0;
}

template<class datatype>
Cirqueue<datatype>::Cirqueue(int max)
{
	maxsize = max+1;
	base = new datatype[maxsize];
	front = rear = 0;
}

template<class datatype>
Cirqueue<datatype>::~Cirqueue()
{
	delete base;
}

template<class datatype>
bool Cirqueue<datatype>::empty()
{
	return front == rear;
}


template<class datatype>
bool Cirqueue<datatype>::full()
{
	return (rear + 1) % maxsize == front;
}

template<class datatype>
int  Cirqueue<datatype>::getlength()
{
	return (rear - front + maxsize) % maxsize;
}


template<class datatype>
void Cirqueue<datatype>::enqueue(datatype value)
{
	if (full())
		cout << "队列已满" << endl;
	else
	{
		base[rear] = value;
		rear++;
	}
}

template<class datatype>
void  Cirqueue<datatype>::dequeue()
{
	if (empty())
		cout << "队列为空" << endl;
	else
		front = (front + 1) % maxsize;
}

template<class datatype>
datatype Cirqueue<datatype>::getfront()
{
	return base[front];
}

template<class datatype>
datatype Cirqueue<datatype>::getrear()
{
	return base[rear-1];
}

int main()
{
	//test
	Cirqueue<int> A(3);
	A.enqueue(1);
	A.enqueue(2);
	A.dequeue();
	A.enqueue(4);
	A.enqueue(4);
	cout << A;
	cout << A.getlength() << " " << A.getfront() <<" "<<A.getrear()<< endl;
	system("pause");
	return 0;
}

2.链队的实现:

#include<iostream>
using namespace std;
template<class datatype>
class Linkqueue;

template<class datatype>
class node
{
public:
	//friend class Linkqueue<datatype>;
	datatype data;
	node<datatype> *next;
	node(datatype x) : data(x), next(NULL) {};
};

template<class datatype>
class Linkqueue
{
private:
	node<datatype> *front;
	node<datatype> *rear;
	int len;
public:
	Linkqueue();
	~Linkqueue();
	void inqueue(datatype val);
	void dequeue();
	int getlen1();
	int getlen2();
	datatype getfront()
	{
		return front->next->data;
	}
	datatype getrear()
	{
		return rear->data;
	}
	friend ostream &operator<<(ostream &output, const Linkqueue &D)
	{
		if (D.len == 0)
		{
			cout << "Linkqueue is empty" << endl;
		}
		else
		{
			node<datatype> *p = D.front->next;
			for (int i = 0; i < D.len; i++)
			{
				cout << p->data << " ";
				p = p->next;
			}
			cout << endl;
		}
		return output;
	}
};

template<class datatype>
Linkqueue<datatype>::Linkqueue()
{
	front = new node<datatype>(-1);
	rear = front;
	front->next = NULL;
	len = 0;
}

template<class datatype>
Linkqueue<datatype>::~Linkqueue()
{
	while (rear != front)
	{
		node<datatype> *temp = front->next;
		delete front;
		front = temp;
	}
	delete rear;
}


template<class datatype>
void Linkqueue<datatype>::inqueue(datatype val)
{
	rear->next = new node<datatype>(val);
	rear = rear->next;
	len++;
}

template<class datatype>
void Linkqueue<datatype>::dequeue()
{
	if (len == 0)
	{
		cerr << "Linkqueue is empty,can't dequeue" << endl;
	}
	else
	{
		node<datatype> *temp = front->next;
		front->next = front->next->next;
		delete temp;
		len--;
	}
}
template<class datatype>
int Linkqueue<datatype>::getlen1()
{
	return len;
}

template<class datatype>
int Linkqueue<datatype>::getlen2()
{
	node<datatype> *temp = front;
	int count = 0;
	while (temp != rear)
	{
		count++;
		temp = temp->next;
	}
	return count;
}
int main()
{
	//test
	Linkqueue<int> A;
	A.inqueue(3);
	A.inqueue(2);
	A.inqueue(1);
	A.inqueue(4);
	cout << A;
	cout << A.getlen2() << endl;
	cout << A.getfront() << " " << A.getrear() << endl;
	A.dequeue();
	A.dequeue();
	A.dequeue();
	cout << A;
	system("pause");
	return 0;
}

栈和队列的区别:

  • 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
  • 栈是先进后出,队列是先进先出。
  • 栈只允许在表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除。
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈乐乐happy

觉得对你有用的话可以打赏打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值