欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-10 22:35:45
2020年8月8日 周六 天气晴 【不悲叹过去,不荒废现在,不惧怕未来】本文目录1. 引言2. 主文件——main.cpp3. 顺序栈类.h文件——sqstack.h4. 链栈类.h文件——linkstack.h5. 预编译头文件——stdafx.h参考文献1. 引言用C++实现了简单的顺序栈和链栈类,成员函数实现了栈的基础功能:isEmpty(),push(),pop(),top(),并且用实现的栈解决了两个问题:进制转换和判断表达式是否有效,代码是用VS2019实现的,每个函数的功能都添加了一...

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



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	   345916208@qq.com
 *  @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<ElemType>::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 <bits/stdc++.h> // 万能的头文件,可能需要手动加入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

本文地址:https://blog.csdn.net/m0_37433111/article/details/107883231