线性表:实现单链表和子类栈(Stack)及单向队列(Queue) [C++]
刚刚开始学习c++。之前c的内容掌握的也不多,基本只是一本概论课的程度,以前使用c的struct写过的链表、用python写过简单的数据结构,就试着把两者用c++写出来,也是对c++的class,以及继承中的public/protected/private的性质进行初步了解。第一次写头文件.h和源文件.cpp分开的c++代码。过程中参考了ProLyn和kgvito的代码,基本就是百度“单链表 c++”的前几个搜索结果。
节点listNode还是用struct来写了,因为我想节点除了构造没有什么方法需要实现,变量和构造也总是需要处于public的状态方便其他类函数调用。
栈是保持先进后出(First In Last Out, 或者FILO)的数据结构,在这里只是定义了最基本的五种方法,实现从尾部添加、从尾部弹出;队列是保持先进先出(First In First Out, FIFO)的数据结构,同样定义了最基本的方法实现从尾部添加从头部弹出。二者我都使用了private继承,因为除了重新封装list的几种方法外,多数list的方法都不需要出现在这两种数据结构中,我认为禁止public访问这些方法比较好。
// linked_list.h
// Base class linked list "linkList", derived "linkStack" & "linkQueue"
typedef int DataType; // constructing struct "listNode"
struct listNode
{
DataType nodeVal;
listNode* nextNode;
listNode(const DataType x); // listNode construct func
}; // constructing base class "linklist"
class linkList
{
private: // private variables headNode & tailNode
listNode* headNode;
listNode* tailNode;
// construction functions, and operator overload
public:
linkList();
linkList(const linkList& lista);
linkList& operator=(linkList& lista);
DataType operator[](int index);
// other functions, public
public:
bool isEmpty();
void PrintList();
void PushBack(const DataType& x);
void PushFront(const DataType& x);
void PopBack();
void PopFront();
DataType PeekBack();
DataType PeekFront();
void InsertNext(listNode* pos, DataType x);
void DeleteNext(listNode* pos);
void Delete(listNode* pos);
void Clear();
void Remove(DataType x);
void RemoveAll(DataType x);
void Sort();
int GetLength();
listNode* Find(DataType x);
}; // derived class linkStack
class linkStack : private linkList
{
public:
linkStack();
linkStack(const linkStack& stack1);
linkStack& operator=(linkStack& stack1);
// the least functions needed
public:
bool isEmpty();
int getSize();
void PushBack(const DataType& x);
void PopBack();
DataType PeekBack();
}; // derived class linkQueue
class linkQueue : private linkList
{
public:
linkQueue();
linkQueue(const linkQueue& queue1);
linkQueue& operator=(linkQueue& queue1); public:
bool isEmpty();
int getSize();
void PushBack(const DataType& x);
void PopFront();
DataType PeekFront();
}
对struct listNode,class linkList, linkStack, linkQueue的方法的具体实现,后两者基本只是对于linkList的重新封装,为了能在private继承的子类中实现,也不得不在linkList中添加了一些没什么用处的函数。其中构造函数和赋值下标运算重载的写法都是现学的…如果现学的不到位请不吝赐教!
#include <iostream>
#include "linked_list.h"
using namespace std;
// construction func for listNode
listNode::listNode(const DataType x)
:nodeVal(x), nextNode(nullptr)
{}
// construction funcs for linkList
linkList::linkList() // without argument
: headNode(nullptr), tailNode(nullptr)
{} linkList::linkList(const linkList& lista) // with argument
: headNode(nullptr), tailNode(nullptr)
{
if (lista.headNode) {
listNode* tmp = lista.headNode;
while (tmp->nextNode) {
PushBack(tmp->nodeVal);
tmp = tmp->nextNode;
}
PushBack(tmp->nodeVal);
}
}
// operator reload =
linkList& linkList::operator=(linkList &lista) {
if (this != &lista) {
swap(headNode, lista.headNode);
swap(tailNode, lista.tailNode);
}
return *this;
}
// operator reload [](index)
DataType linkList::operator[](int index) {
if (index < || headNode == nullptr) {
cout << "Invalid index!" << endl;
return -;
}
else {
listNode* tmp = headNode;
int i;
while (tmp != nullptr && i < index) {
tmp = tmp->nextNode;
i++;
}
if (tmp == nullptr) {
cout << "Invalid index!" << endl;
return -;
}
else {
return tmp->nodeVal;
}
}
} bool linkList::isEmpty() {
if (headNode) {
return true;
}
else {
return false;
}
} int linkList::GetLength() {
int count = ;
listNode* tmp = headNode;
while (tmp) {
count++;
tmp = tmp->nextNode;
}
return count;
} void linkList::PrintList() {
listNode* tmp = headNode;
if (tmp) {
cout << tmp->nodeVal;
tmp = tmp->nextNode;
while (tmp) {
cout << "->" << tmp->nodeVal;
tmp = tmp->nextNode;
}
cout << endl;
}
else {
cout << "Empty linked list!" << endl;
}
} void linkList::PushBack(const DataType& x) {
if (headNode) {
tailNode->nextNode = new listNode(x);
tailNode = tailNode->nextNode;
}
else {
headNode = new listNode(x);
tailNode = headNode;
}
} void linkList::PushFront(const DataType& x) {
if (headNode) {
listNode* tmp = new listNode(x);
tmp->nextNode = headNode;
headNode = tmp;
}
else {
headNode = new listNode(x);
tailNode = headNode;
}
} void linkList::PopBack() {
if (headNode) {
if (headNode->nextNode) {
listNode* tmp = headNode;
while (tmp->nextNode != tailNode) {
tmp = tmp->nextNode;
}
delete tailNode;
tmp->nextNode = nullptr;
tailNode = tmp;
}
else {
delete headNode;
headNode = nullptr;
tailNode = nullptr;
}
}
else {
cout << "Empty linked list!" << endl;
}
} void linkList::PopFront() {
if (headNode) {
if (headNode->nextNode) {
listNode* tmp = headNode->nextNode;
delete headNode;
headNode = tmp;
}
else {
delete headNode;
headNode = nullptr;
tailNode = nullptr;
}
}
else {
cout << "Empty linked list!" << endl;
}
} DataType linkList::PeekBack() {
if (tailNode) {
return tailNode->nodeVal;
}
else {
cout << "Empty linked list!" << endl;
return -;
}
} DataType linkList::PeekFront() {
if (headNode) {
return headNode->nodeVal;
}
else {
cout << "Empty linked list!" << endl;
return -;
}
} listNode* linkList::Find(DataType x) {
listNode* targetNode = headNode;
while (targetNode) {
if (targetNode->nodeVal == x) {break;}
}
return targetNode;
} void linkList::InsertNext(listNode* pos, DataType x) {
if (pos) {
if (pos == tailNode) {
listNode* tmp = new listNode(x);
pos->nextNode = tmp;
tailNode = tmp;
}
else {
listNode* tmp = new listNode(x);
tmp->nextNode = pos->nextNode;
pos->nextNode = tmp;
}
}
else {
cout << "Invalid position!" << endl;
}
} void linkList::DeleteNext(listNode* pos) {
if (pos) {
if (pos == tailNode) {
cout << "Invalid node!" << endl;
}
else {
listNode* tmp = (pos->nextNode)->nextNode;
delete pos->nextNode;
pos->nextNode = tmp;
}
}
else {
cout << "Invalid node!" << endl;
}
} void linkList::Remove(DataType x) {
if (headNode) {
if (headNode->nextNode) {
listNode* tmp = headNode;
while (tmp->nextNode) {
if ((tmp->nextNode)->nodeVal == x) {
DeleteNext(tmp);
break;
}
tmp = tmp->nextNode;
}
}
else {
if (headNode->nodeVal == x) {PopFront();}
}
}
} void linkList::RemoveAll(DataType x) {
if (headNode) {
listNode* tmp = headNode;
while (tmp->nextNode) {
if ((tmp->nextNode)->nodeVal == x) {
if (tmp->nextNode == tailNode){
PopBack();
break;
}
else {DeleteNext(tmp);}
}
tmp = tmp->nextNode;
}
if (tmp->nodeVal == x) {
PopBack();
}
}
} void linkList::Clear() {
if (headNode) {
listNode* prev = headNode;
listNode* tmp;
while (prev->nextNode) {
tmp = prev->nextNode;
delete prev;
prev = tmp;
}
headNode = nullptr;
tailNode = nullptr;
}
}
// construction funcs for linkStack
linkStack::linkStack() // without arguments
:linkList()
{} linkStack::linkStack(const linkStack& stack1) // with an argument
:linkList(stack1)
{}
// other public funcs for linkStack
bool linkStack::isEmpty() {
return linkList::isEmpty();
} int linkStack::getSize() {
return linkList::GetLength();
} void linkStack::PushBack(const DataType& x) {
linkList::PushBack(x);
} void linkStack::PopBack() {
linkList::PopBack();
} DataType linkStack::PeekBack() {
return linkList::PeekBack();
}
// construction funcs for linkQueue
linkQueue::linkQueue()
:linkList()
{} linkQueue::linkQueue(const linkQueue& queue1)
:linkList(queue1)
{}
// other public funcs for linkQueue
bool linkQueue::isEmpty() {
return linkList::isEmpty();
} int linkQueue::getSize() {
return linkList::GetLength();
} void linkQueue::PushBack(const DataType& x) {
linkList::PushBack(x);
} void linkQueue::PopFront() {
linkList::PopFront();
} DataType linkQueue::PeekFront() {
return linkList::PeekFront();
}
最后还有测试代码,和主题没什么关系,但是从以前用python学习数据结构开始我就喜好把测试代码写成假交互式,所以索性贴在这里方便取用。
#include <iostream>
#include "linked_list.h"
#include <stdlib.h>
#include <map> using namespace std; static map<string, int>stringVal {
{"Exit", },
{"Printlist", },
{"Pushback", },
{"Pushfront", },
{"Popback", },
{"Popfront", },
{"Clear", },
{"Remove", },
{"Removeall", },
{"Sort", },
{"Getlength", },
{"Index", },
{"Peekback", },
{"Peekfront", }
}; int test_list() {
linkList list1;
cout << ">> Linked list tesing.\n"
">> Enter a direction, namely Printlist, Pushback, Pushfront, Popback, Peekback, "
"Popfront, Peekfront, Clear, Remove, Removeall, Sort, Getlength or Index,"
"enter Exit to exit." << endl;
string direction;
DataType parameter;
int param;
while () {
cout << ">> ";
cout.flush();
cin >> direction;
switch(stringVal[direction])
{
case :
return ;
case :
list1.PrintList();
break;
case :
cin >> parameter;
list1.PushBack(parameter);
break;
case :
cin >> parameter;
list1.PushFront(parameter);
break;
case :
list1.PopBack();
break;
case :
list1.PopFront();
break;
case :
list1.Clear();
break;
case :
cin >> parameter;
list1.Remove(parameter);
break;
case :
cin >> parameter;
list1.RemoveAll(parameter);
break;
/* case 9:
list1.Sort();
break;*/
case :
param = list1.GetLength();
cout << ">> " << param << endl;
break;
case :
cin >> param;
parameter = list1[param];
cout << ">> " << parameter << endl;
break;
case :
parameter = list1.PeekBack();
cout << ">> " << parameter << endl;
break;
case :
parameter = list1.PeekFront();
cout << ">> " << parameter << endl;
}
}
return ;
} int test_stack() {
linkStack stack1;
cout << ">> Linked list stack tesing.\n"
">> Enter a direction, namely Pushback, Popback or Peekback, "
"enter Exit to exit." << endl;
string direction;
DataType parameter;
int param;
while () {
cout << ">> ";
cout.flush();
cin >> direction;
switch(stringVal[direction])
{
case :
return ;
case :
cin >> parameter;
stack1.PushBack(parameter);
break;
case :
stack1.PopBack();
break;
case :
parameter = stack1.PeekBack();
cout << ">> " << parameter << endl;
break;
}
}
return ;
} int main() {
test_stack();
return ;
}
假交互式测试代码, test(), main()
线性表:实现单链表和子类栈(Stack)及单向队列(Queue) [C++]的更多相关文章
- 线性表之单链表C++实现
线性表之单链表 一.头文件:LinkedList.h //单链表是用一组任意的存储单元存放线性表的元素,这组单元可以是连续的也可以是不连续的,甚至可以是零散分布在内存中的任意位置. //单链表头文件 ...
- [数据结构 - 第3章] 线性表之单链表(C++实现)
一.类定义 单链表类的定义如下: #ifndef SIGNALLIST_H #define SIGNALLIST_H typedef int ElemType; /* "ElemType类型 ...
- 续上文----线性表之单链表(C实现)
本文绪上文线性表之顺序表(C实现) 本文将继续使用单链表实现线性表的另外一种存储结构.这种使用链表实现的存储结构在内存中是不连续的. C实现代码如下: #include<stdio.h> ...
- 【Java】 大话数据结构(2) 线性表之单链表
本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...
- 线性表 (单链表、循环链表-python实现)
一.线性表 线性表的定义: 线性表是具有相同数据类型的有限数据的序列. 线性表的特点: 出了第一个元素外,每个元素有且仅有一个直接前驱,除最后一个元素外有且只有一个后继. 线性表是一种逻辑结构,表示元 ...
- Java数据结构-线性表之单链表LinkedList
线性表的链式存储结构,也称之为链式表,链表:链表的存储单元能够连续也能够不连续. 链表中的节点包括数据域和指针域.数据域为存储数据元素信息的域,指针域为存储直接后继位置(一般称为指针)的域. 注意一个 ...
- [C++]数据结构:线性表之(单)链表
一 (单)链表 ADT + Status InitList(LinkList &L) 初始化(单)链表 + void printList(LinkList L) 遍历(单)链表 + int L ...
- 数据结构(java版)学习笔记(三)——线性表之单链表
单链表的优点: 长度不固定,可以任意增删. 单链表的缺点: 存储密度小,因为每个数据元素,都需要额外存储一个指向下一元素的指针(双链表则需要两个指针). 要访问特定元素,只能从链表头开始,遍历到该元素 ...
- 【线性表基础】顺序表和单链表的插入、删除等基本操作【Java版】
本文表述了线性表及其基本操作的代码[Java实现] 参考书籍 :<数据结构 --Java语言描述>/刘小晶 ,杜选主编 线性表需要的基本功能有:动态地增长或收缩:对线性表的任何数据元素进行 ...
随机推荐
- 第五章 面向方面编程___AOP入门
上一篇讲了 AOP 和 OOP 的区别,这一次我们开始入门 AOP .实现面向方面编程的技术,主要分为两大类: 一是 采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行: ...
- 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean
7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...
- Mysql全文搜索match against的用法
全文检索在 MySQL 中就是一个 FULLTEXT 类型索引.FULLTEXT 索引用于 MyISAM 表,可以在 CREATE TABLE 时或之后使用 ALTER TABLE 或 CREATE ...
- codeblocks中cocos2dx项目添加新的.cpp和.h文件后编译运行的方法
新建了cocos2dx项目后(比如我这里建立的项目名为Test01),项目目录下有如下目录和文件: bin CMakeLists.txt MyGame.layout proj.win10 Classe ...
- MUI 图标筛选切换(父页面传值子页面)
1 父页面: index.html <li class="tab_layout"> <a href="javascript:;" clas ...
- ruby+gem常用命令
gem是一种文件组织的包,一般的ruby的很多插件都有由这种各种的包提供.我们来看看gem的用法 ruby -v #查看ruby 版本 ruby -e ''require"watir ...
- 报错 ERROR in static/js/vendor.b3f56e9e0cd56988d890.js from UglifyJs
开发vux项目在引入 // 表单验证组件-start import zh_CN from 'vee-validate/dist/locale/zh_CN' import Validator from ...
- HFS的远程命令执行漏洞(RCE)
一.HFS漏洞 1.影响版本 : 2.3c以前的2.3x版本 2.HFS: HFS是HTTP File Server,国外的一款HTTP 文件服务器软件,简单易上手. 3.漏洞描述: HTTP Fil ...
- Android通知栏的高度获取
public static int getStatusBarHeight(Context context){ Class<?> c = null; Object obj = null; F ...
- rest_framework之版本详解 04
访问不同版本,给不同内容. rest规范:版本要么放url上:要么放请求头里. 1.原来的url的版本都写死了.只能写v1 from django.conf.urls import url from ...