C++实现数据结构——顺序栈和链栈

2020年8月8日 周六 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】


本文目录

    • 1. 引言
    • 2. 主文件——main.cpp
    • 3. 顺序栈类 .h文件——sqstack.h
    • 4. 链栈类 .h文件——linkstack.h
    • 5. 预编译头文件——stdafx.h
    • 参考文献


1. 引言

用C++实现了简单的顺序栈和链栈类,成员函数实现了栈的基础功能:isEmpty(),push(),pop(),top(),并且用实现的栈解决了两个问题:进制转换和判断表达式是否有效,代码是用VS2019实现的,每个函数的功能都添加了一定注释,由于用了模板,函数的声明和定义都放在了.h文件中,完整工程放在了我的github上,有需要的也可以自取。

github地址:https://github.com/March225/Data-structure-implemented-by-Cpp

2. 主文件——main.cpp

/**
 *  @Copyright (C) 2020 March. All rights reserved.
 *  @license   GNU General Public License (GPL)
 *  @author	   March
 *  @email	   [email protected]
 *  @file	   main.cpp
 *  @brief	   顺序栈和链栈的C++实现主文件
 *  @version   1.0
 *  @date	   2020-07-31
 */

#include "stdafx.h"
#include "solution.h"


int main()
{
	FILE* stream1;
	ios::sync_with_stdio(false); // 让c风格的输入输出流和c++的输入输出流分开,使cin读入的更快
	freopen_s(&stream1, "1.in", "r", stdin); // 直接从文档中读取待输入的数据

	// 利用顺序栈或链栈将10进制数转换为16进制数,输入文件为“1.in”
	int n = 0;
	cin >> n;
	for (int i = 0; i < n; ++i) {
		int num = 0;
		cin >> num;
		cout << num << " 转换为16进制为:" << Solution().DecToHex(num) << endl;
	}

// 	// 利用顺序栈或链栈判断一个表达式是否有效(即:三种括号是否匹配),输入文件为“2.in”
// 	string s = "";
// 	int cnt = 0;
// 	while (getline(cin, s)) {
// 		if (Solution().isValidOfExpression(s))
// 			cout << ++cnt << ": yes!" << endl;
// 		else
// 			cout << ++cnt << ": no!" << endl;
// 	}

	return 0;
}

3. 顺序栈类 .h文件——sqstack.h

#pragma once
#include "stdafx.h"

/**
 * @brief 创建一个顺序栈类
 */
template <typename ElemType>
class SqStack
{
public:
	SqStack();
	~SqStack();

	bool isEmpty(); // 判断顺序栈是否为空
	bool isFull();	// 判断顺序栈是否已满
	bool push(ElemType val); // 向顺序栈压入一个元素
	bool pop(); // 删除顺序栈顶端的元素
	ElemType top(); // 返回顺序栈顶端的元素但不删除

private:
	ElemType* elem_; // 声明顺序栈的基地址
	int top_; // 声明顺序栈的栈顶索引
};

// 构造函数,初始化基地址和栈顶索引
template <typename ElemType>
SqStack<ElemType>::SqStack():top_(-1)
{
	elem_ = new ElemType[kMaxSize];   // 开辟空间
	if (!elem_) {                     // 当溢出时报异常
		exit(OVERFLOW);
	}
}

// 构造函数,销毁顺序栈
template <typename ElemType>
SqStack<ElemType>::~SqStack()
{
	delete[] elem_;
}

// 判断顺序栈是否为空
template <typename ElemType>
bool SqStack<ElemType>::isEmpty()
{
	return top_ == -1;
}

// 判断顺序栈是否已满
template <typename ElemType>
bool SqStack<ElemType>::isFull()
{
	return top_ == kMaxSize - 1;
}

// 向顺序栈压入一个元素
template <typename ElemType>
bool SqStack<ElemType>::push(ElemType val)
{
	if (isFull()) {
		return false;
	}
	else {
		elem_[++top_] = val;
		return true;
	}
}

// 删除顺序栈顶端的元素
template <typename ElemType>
bool SqStack<ElemType>::pop()
{
	if (isEmpty()) {
		return false;
	}
	else {
		top_--;
		return true;
	}
}

// 返回顺序栈顶端的元素但不删除
template <typename ElemType>
ElemType SqStack<ElemType>::top()
{
	if (isEmpty()) {
		return NULL;
	}
	else
		return elem_[top_];
}

4. 链栈类 .h文件——linkstack.h

linkstack.h文件:

#pragma once
#include "stdafx.h"

/**
 * @brief 创建一个链栈类
 */
template <typename ElemType>
class LinkStack
{
public:
	LinkStack();
	~LinkStack();

	bool isEmpty(); // 判断链栈是否为空
	bool push(ElemType val); // 向链栈压入一个元素
	bool pop(); // 删除链栈顶端的元素
	ElemType top(); // 返回链栈顶端的元素但不删除

private:
	StackNode<ElemType>* top_; // 声明链栈的头结点
	int length_; // 声明链栈的长度
};

// 构造函数,初始化链栈的头结点
template <typename ElemType>
LinkStack<ElemType>::LinkStack()
{
	top_ = new StackNode<ElemType>();
	if (!top_)
		cerr << "Space allocating falied! Error in LinkStack::LinkStack()!" << endl;
	length_ = 0;
}

// 析构函数,销毁链栈
template <typename ElemType>
LinkStack<ElemType>::~LinkStack()
{
	while (top_)
	{
		StackNode<ElemType>* cur = top_;
		top_ = top_->next;
		delete cur;
	}
}

// 判断链栈是否为空
template <typename ElemType>
bool LinkStack<ElemType>::isEmpty()
{
	return top_->next == nullptr;
}

// 向链栈压入一个元素
template <typename ElemType>
bool LinkStack<ElemType>::push(ElemType val)
{
	StackNode<ElemType>* new_node = new StackNode<ElemType>(val);
	if (!new_node) {
		cerr << "Space allocating falied!" << endl;
		return false;
	}
	else {
		new_node->next = top_;
		top_ = new_node;
		++length_;
	}
	return true;
}

// 删除链栈顶端的元素
template <typename ElemType>
bool LinkStack<ElemType>::pop()
{
	if (isEmpty())
		return false; 
	else {
		StackNode<ElemType>* tmp = top_;
		top_ = top_->next;
		delete tmp;
		--length_;
	}
	return true;
}

// 返回链栈顶端的元素但不删除
template <typename ElemType>
ElemType LinkStack<ElemType>::top()
{
	if (isEmpty()) {
		return NULL;
	}
	else
		return top_->val;
}

5. 预编译头文件——stdafx.h

#pragma once
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#if !defined(AFX_STDAFX_H__D36E9D40_3BCB_4A85_9D48_AC876E7A2942__INCLUDED_)
#define AFX_STDAFX_H__D36E9D40_3BCB_4A85_9D48_AC876E7A2942__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include  // 万能的头文件,可能需要手动加入include文件夹中

const int kMaxSize = 100000; // 顺序栈的最大长度
using namespace std;

/**
 * @brief 定义链栈的结点
 */
template <typename ElemType>
struct StackNode {
	ElemType val;
	StackNode<ElemType>* next;
	// 这里 val() 意思是初始化为空,不写也可以
	StackNode() : val(), next(nullptr) {}
	StackNode(ElemType x) : val(x), next(nullptr) {}
};

#endif // !defined(AFX_STDAFX_H__D36E9D40_3BCB_4A85_9D48_AC876E7A2942__INCLUDED_)

参考文献

https://blog.csdn.net/my_mao/article/details/23255693
https://blog.csdn.net/chczy1/article/details/78255135?utm_source=jiancool
https://blog.csdn.net/weixin_39469127/article/details/80431872?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param
https://www.cnblogs.com/25th-engineer/p/9940191.html

你可能感兴趣的:(研究生生活——数据结构,c++,栈,stack)