刚刚开始学习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++]的更多相关文章

  1. 线性表之单链表C++实现

    线性表之单链表 一.头文件:LinkedList.h //单链表是用一组任意的存储单元存放线性表的元素,这组单元可以是连续的也可以是不连续的,甚至可以是零散分布在内存中的任意位置. //单链表头文件 ...

  2. [数据结构 - 第3章] 线性表之单链表(C++实现)

    一.类定义 单链表类的定义如下: #ifndef SIGNALLIST_H #define SIGNALLIST_H typedef int ElemType; /* "ElemType类型 ...

  3. 续上文----线性表之单链表(C实现)

    本文绪上文线性表之顺序表(C实现) 本文将继续使用单链表实现线性表的另外一种存储结构.这种使用链表实现的存储结构在内存中是不连续的. C实现代码如下: #include<stdio.h> ...

  4. 【Java】 大话数据结构(2) 线性表之单链表

    本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...

  5. 线性表 (单链表、循环链表-python实现)

    一.线性表 线性表的定义: 线性表是具有相同数据类型的有限数据的序列. 线性表的特点: 出了第一个元素外,每个元素有且仅有一个直接前驱,除最后一个元素外有且只有一个后继. 线性表是一种逻辑结构,表示元 ...

  6. Java数据结构-线性表之单链表LinkedList

    线性表的链式存储结构,也称之为链式表,链表:链表的存储单元能够连续也能够不连续. 链表中的节点包括数据域和指针域.数据域为存储数据元素信息的域,指针域为存储直接后继位置(一般称为指针)的域. 注意一个 ...

  7. [C++]数据结构:线性表之(单)链表

    一 (单)链表 ADT + Status InitList(LinkList &L) 初始化(单)链表 + void printList(LinkList L) 遍历(单)链表 + int L ...

  8. 数据结构(java版)学习笔记(三)——线性表之单链表

    单链表的优点: 长度不固定,可以任意增删. 单链表的缺点: 存储密度小,因为每个数据元素,都需要额外存储一个指向下一元素的指针(双链表则需要两个指针). 要访问特定元素,只能从链表头开始,遍历到该元素 ...

  9. 【线性表基础】顺序表和单链表的插入、删除等基本操作【Java版】

    本文表述了线性表及其基本操作的代码[Java实现] 参考书籍 :<数据结构 --Java语言描述>/刘小晶 ,杜选主编 线性表需要的基本功能有:动态地增长或收缩:对线性表的任何数据元素进行 ...

随机推荐

  1. 把握linux内核设计思想(七):内核定时器和定时运行

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途]         前面章节说到了把工作推后到除如今以外的时间运行的机制是下半部机 ...

  2. Java课后简答题

    1.简述Java的特点. 面向对象.跨平台性.健壮性.安全性.可移植性.多线程性.动态性等. 2.简述JRE与JDK的区别. JRE(Java Runtime Environment,Java运行时环 ...

  3. swift - UIAlertController 的用法

    ios 8 以后苹果官方建议使用UIAlertController这个类,所以专门去网上找资料,了解了下用法, 1.创建一个alertController let alertController = ...

  4. swift - UISlider 的用法

    swift的UISlider的用法和oc基本没有区别 1.创建 class SecondViewController: UIViewController { var slider = UISlider ...

  5. PyQt4预定义对话框

    PyQt4中的对话框 对话窗口和对话框是现代GUI应用程序必不可少的一部分.生活中“对话”被定义为发生在两人或更多人之间的会话.而在计算机世界,“对话”则时人与应用程序之间的“会话”.人及对话的形式有 ...

  6. poj_2315 最小费用最大流

    题目大意 一个图上有N个顶点,从1到N标号,顶点之间存在一些无向边,边有长度,要求从顶点1走到顶点N,再从顶点N走回顶点1,其中不必要经过每个顶点,但是要求走的路径上的边只能经过一次.求出从1---& ...

  7. [SCOI2008] 着色方案[高维dp]

    321. [SCOI2008] 着色方案 ★★★   输入文件:color.in   输出文件:color.out   简单对比时间限制:1 s   内存限制:64 MB 题目背景: 有n个木块排成一 ...

  8. IT公司常见的内网漏洞表格

    访问控制类漏洞与隐患 这一类漏洞与隐患属于访问控制与身份鉴别问题,一般有没有配置访问控制.访问控制弱(弱口令或者空口令),身份鉴别可以绕过等问题 漏洞协议组件 漏洞类型 漏洞评级 SSH 弱口令 严重 ...

  9. Java初学者笔记三:关于字符串和自实现数组常见操作以及异常处理

    一.字符串常见的操作 1.结合我在python中对于字符串常见处理总结出下面三个应该能算是字符串造作的TOP 3 //字符串查找子串,存在返回index,不存在返回-1 等于python的find: ...

  10. WEB安全第六篇--千里之外奇袭客户端:XSS和HTML注入

    零.前言 最近做专心web安全有一段时间了,但是目测后面的活会有些复杂,涉及到更多的中间件.底层安全.漏洞研究与安全建设等越来越复杂的东东,所以在这里想写一个系列关于web安全基础以及一些讨巧的pay ...