栈、单队列、双队列的C++实现

前言

继上次用C++实现链表后,这次记录的是用C++实现栈和队列。经过上次的实现,现在对C++已经不那么陌生了,这次的实现几乎是一遍通过的。

代码

话不多说,上代码:
首先是CNode.h

#ifndef _NODE_H__
#define _NODE_H__

class CNode{
private:
	int data;
	CNode *nextNode;
public:
	CNode();
	void setData(int iData);
	int getData() const;
	void setNextNode(CNode *nextNode);
	CNode* getNextNode() const;
};

#endif

以及DNode.h

#ifndef _DNODE_H__
#define _DNODE_H__
class DNode{
private:
	int data;
	DNode *preNode;
	DNode *nextNode;
public:
	DNode(){
		this->preNode = NULL;
		this->nextNode = NULL;
	};
	void setData(int iData){
		data = iData;
	};
	int getData() const{
		return data;
	};
	void setNextNode(DNode *nextNode){
		this->nextNode = nextNode;
	};
	void setPreNode(DNode *preNode){
		this->preNode = preNode;
	};
	DNode* getPreNode() const{
		return preNode;
	};
	DNode* getNextNode() const{
		return nextNode;
	};
};
#endif

然后是Stack.h

#include "CNode.h"

class Stack {
private:
	CNode *top;
public:
	Stack();
	~Stack();
	void Push(int value);
	void Pop();
	int Peek();
	bool IsEmpty();
};

接下来是Queue.h:

#pragma once
#include "CNode.h"

class Queue {
private:
	CNode * front;
	int data;

public:
	Queue();
	~Queue();

	void Enqueue(int value);
	void Dequeue();
	int Peek();
	bool IsEmpty();
};

接下来是Deque.h

#pragma once
#include "DNode.h"
#include "Queue.h"
class Deque :Queue{
private:
	DNode *front;
	DNode *back;
	int data;
public:
	Deque();
	~Deque();
	void Enqueue_Front(int value);
	void Enqueue_Back(int value);
	void Dequeue_Front();
	void Dequeue_Back();
	int Peek_Front();
	int Peek_Back();
	bool IsEmpty();
};

最后是main.cpp

#include <iostream>
#include "CNode.h"
#include "Deque.h"
#include "Queue.h"
#include "Stack.h"
using namespace std;
CNode::CNode(){
	this->nextNode = NULL;
};
void CNode::setData(int iData){
	this->data = iData;
};
int CNode::getData() const{
	return data;
}
void CNode::setNextNode(CNode *nextNode){
	this->nextNode = nextNode;
};
CNode* CNode::getNextNode() const{
	return nextNode;
};
Stack::Stack(){
	top = NULL;
};
Stack::~Stack(){
};
void Stack::Push(int value){
	CNode *s = new CNode;
	s->setData(value);
	if (IsEmpty()) top = s;
	else { 
		s->setNextNode(top); 
		top = s;//reset top node
	}
	return;
};
void Stack::Pop(){
	if (IsEmpty()) ;
	else top = top->getNextNode();
	return;
};
int Stack::Peek(){
	if (IsEmpty()) {
		cout << "ERROR ";
		return -1; 
	}
	else return top->getData();
};
bool Stack::IsEmpty(){
	if (top == NULL) return true;
	else return false;
};
Queue::Queue(){
	this->front = NULL;
	data = 0;
};
Queue::~Queue(){

};
void Queue::Enqueue(int value){
	data += 1;
	CNode *s = new CNode;
	CNode *p = new CNode;
	s->setData(value);
	p = front;
	if (p == NULL) { 
		front = s; 
		return;
	}
	while (p->getNextNode() != NULL) p = p->getNextNode();
	p->setNextNode(s);
	return;
};
void Queue::Dequeue(){
	data -= 1;
	if (front == NULL)return;
	front = front->getNextNode();
	return;
};
int Queue::Peek(){
	return front->getData();
};
bool Queue::IsEmpty(){
	if (data == 0)return true;
	//if(front==NULL) return true
	else return false;
};
Deque::Deque(){
	this->front = NULL;
	this->back = NULL;
	data = 0;
};
Deque::~Deque(){

};
void Deque::Enqueue_Front(int value){
	data += 1;
	DNode *s=new DNode;
	s->setData(value);
	if (front == NULL){
		front = s;
		back = front;
		return;
	}
	s->setNextNode(front);
	front->setPreNode(s);
	front = s;//reset front node
	return;
};
void Deque::Enqueue_Back(int value){
	data += 1;
	DNode *s=new DNode;
	s->setData(value);
	if (IsEmpty()){
		front = s;
		back = front;
		return;
	}
	back->setNextNode(s);
	s->setPreNode(back);
	back = s;//reset back node
	return;
};
void Deque::Dequeue_Front(){
	data -= 1;
	if (IsEmpty()) return;
	else if (front == back){
		front = NULL;
		back = NULL;
		return;
	}
	front = front->getNextNode();
	return;
};
void Deque::Dequeue_Back(){
	data -= 1;
	if (IsEmpty()) return;
	else if (front == back){
		front = NULL;
		back = NULL;
		return;
	}
	back=back->getPreNode();
	return;
};
int Deque::Peek_Front(){
	if (IsEmpty()) {
		cout << "ERROR ";
		return -1;
	}
	return front->getData();
};
int Deque::Peek_Back(){
	if (IsEmpty()) {
		cout << "ERROR ";
		return -1;
	}
	return back->getData();
};
bool Deque::IsEmpty(){
	if (data==0) return true;
	//if(front==NULL) return true
	else return false;
};
int main(){
	Stack s;
	Queue q;
	Deque d;
	//the output should be 1 1 2 0 1 1
	cout << "The output of stack test harness should be 1 1 2 0 1 1"<<endl;
	cout << s.IsEmpty() << endl;//true, so 1
	s.Push(1);
	cout << s.Peek() << endl;//the top should be 1
	s.Push(2);
	cout << s.Peek() << endl;//the top should be 2
	cout << s.IsEmpty() << endl;//false, so 0
	s.Pop();
	cout << s.Peek() << endl;//the top should be 1
	s.Pop();
	cout << s.IsEmpty() << endl;//true, so 1
	//the output should be 1 1 1 0 2 1
	cout << "The output of queue test harness should be 1 1 1 0 2 1" << endl;
	cout << q.IsEmpty() << endl;//true, so 1
	q.Enqueue(1);
	cout << q.Peek() << endl;//the front should be 1
	q.Enqueue(2);
	cout << q.Peek() << endl;//the front should be 1
	cout << q.IsEmpty() << endl;//false,so 0
	q.Dequeue();
	cout << q.Peek() << endl;//the front should be 2
	q.Dequeue();
	cout << q.IsEmpty() << endl;//true, so 1
	//the output should be 1 3 2 0 1 1 1
	cout << "The output of deque test harness should be 1 3 2 0 1 1 1" << endl;
	cout << d.IsEmpty() << endl;//should be 1
	d.Enqueue_Front(1);
	d.Enqueue_Back(2);
	d.Enqueue_Front(3);
	cout << d.Peek_Front() << endl;//should be 3
	cout << d.Peek_Back() << endl;//should be 2
	d.Dequeue_Front();
	d.Dequeue_Back();
	cout << d.IsEmpty() << endl;//should be 0
	cout << d.Peek_Front() << endl;//should be 1
	cout << d.Peek_Back() << endl;//should be 1
	d.Dequeue_Front();
	cout << d.IsEmpty() << endl;//should be 1
}

注意点

过程当中没有遇到什么大问题,唯一查了资料的是在定义.h文件时使用到的#ifndef,#endif等字段。
#ifndef
#表明是预处理命令,ifndef意为if not defined sth.
它与ifdef都可用于条件编译,即:
#ifdef 标识符< A >
程序段1
#else
程序段2
#endif
意为若所指定的标识符A已经被#define命令定义过则编译程序段1,否则编译程序段2。

同理:
#ifndef 标识符< B >
程序段1
#else
程序段2
#endif
意为若所指定的标识符B未被#define命令定义过则编译程序段1,否则编译程序段2。

<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

#ifndef _STDIO_H_ 

它的主要作用是用来防止头文件的重复包含和编译。
比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。如果把头文件的内容都放在#ifndef和#endif中,不管你的头文件会不会被多个文件引用,你都要加上这个,就可以避免冲突的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值