目录:
- List
- Stack -> 其他:普通的类继承 & 模板类继承
- Queue
- Tree & TreeNode & TestTree -> 简单的递归
1. List 定义
//
// Created by on 2021/7/23.
//
#ifndef PRACTICE15_LIST_H
#define PRACTICE15_LIST_H
#include <iostream>
#include "ListNode.h"
using namespace std;
template<typename NODETYPE>
class List{
public:
bool isEmpty() const {
return firstPtr == nullptr;
}
void print() const {
if (isEmpty()) {
cout << "The list is empty\n\n";
return;
}
ListNode<NODETYPE>* currentPtr{firstPtr};
cout << "The list is: ";
while (currentPtr != nullptr){
cout << currentPtr->data << " ";
currentPtr = currentPtr->nextPtr;
}
cout << "\n\n";
}
~List(){
if(!isEmpty()) {
cout << "Destory is not empty";
ListNode<NODETYPE>* currentPtr{firstPtr};
ListNode<NODETYPE>* tempPtr{nullptr};
while (currentPtr != nullptr){
tempPtr = currentPtr;
cout << tempPtr->data << "\n";
currentPtr = currentPtr -> nextPtr;
delete tempPtr;
}
}
cout << "All nodes destroyed\n\n";
}
// insert front
void insertAtFront(ListNode<NODETYPE>& value) {
ListNode<NODETYPE>* newPtr{getNewNode(value)};
if (isEmpty()) {
firstPtr = lastPtr = newPtr;
}
else {
newPtr->nextPtr = firstPtr;
firstPtr = newPtr;
}
}
// insert back
void insertAtBack(ListNode<NODETYPE>& value) {
ListNode<NODETYPE>* newPtr{getNewNode(value)};
if (isEmpty()){
firstPtr = lastPtr = newPtr;
}
else {
lastPtr->nextPtr = newPtr;
lastPtr = newPtr;
}
}
// delete front
bool removeFromFront(NODETYPE& value) {
if (isEmpty()){
return false;
}
else {
ListNode<NODETYPE>* tempPtr{firstPtr};
if (firstPtr == lastPtr) {
firstPtr = lastPtr = nullptr;
}
else {
firstPtr = firstPtr->nextPtr;
}
value = tempPtr->data;
delete tempPtr;
return true;
}
}
// delete back
bool removeFromBack(NODETYPE& value) {
if (isEmpty()){
return false;
}
else {
ListNode<NODETYPE>* tempPtr{lastPtr};
if(firstPtr == lastPtr) {
firstPtr = lastPtr = nullptr;
}
else {
ListNode<NODETYPE>* currentPtr{firstPtr};
while (currentPtr->nextPtr != lastPtr){
currentPtr = currentPtr -> nextPtr;
}
lastPtr = currentPtr;
currentPtr->nextPtr = nullptr;
}
value = tempPtr->data;
delete tempPtr;
return true;
}
}
private:
ListNode<NODETYPE>* firstPtr{nullptr};
ListNode<NODETYPE>* lastPtr{nullptr};
ListNode<NODETYPE>* getNewNode(const NODETYPE& value) {
return new ListNode<NODETYPE>{value};
}
};
#endif //PRACTICE15_LIST_H
ListNode 定义
//
// Created by on 2021/7/23.
//
#ifndef PRACTICE15_LISTNODE_H
#define PRACTICE15_LISTNODE_H
template<typename NODETYPE> class List; // 类模板
template<typename NODETYPE>
class ListNode{
friend class List<NODETYPE>;
public:
// constuctor
explicit ListNode(const NODETYPE& info):data{info}, nextPtr{nullptr} {}
// return data in node
NODETYPE getData() const {return data;}
private:
// data
NODETYPE data;
ListNode<NODETYPE>* nextPtr;
};
#endif //PRACTICE15_LISTNODE_H
原理:
注意编译的 CMakeLists.txt 的用法哈~~
2、普通的类继承 & 模板类继承
普通的类继承,注意复习虚函数:https://zhuanlan.zhihu.com/p/259875110
#include <iostream>
using namespace std;
class A
{
public:
A() {};
~A() {};
virtual void func(){
cout << "this is A" << endl;
}
};
class B : public A
{
public:
virtual void func() {
cout << "this is B" << endl;
}
};
int main(){
A* c = new B();
c ->func(); //this is B
c ->A::func(); //this is A
B b;
b.func(); //this is B
A a;
a.func(); //this is A
b.A::func(); //this is A
}
/*
*
this is B
this is A
this is B
this is A
this is A
*/
模板类的继承:Stack.h 定义
// Stack class-template definition.
#ifndef STACK_H
#define STACK_H
#include "List.h" // List class definition
template<typename STACKTYPE>
class Stack : private List<STACKTYPE> {
public:
// push calls the List function insertAtFront
void push(const STACKTYPE& data) {
this->insertAtFront(data); // 这里修改成了this
}
// pop calls the List function removeFromFront
bool pop(STACKTYPE& data) {
return this->removeFromFront(data);
}
// isStackEmpty calls the List function isEmpty
bool isStackEmpty() const {
return this->isEmpty();
}
// printStack calls the List function print
void printStack() const {
this->print();
}
};
#endif
测试stack 小程序
#include <iostream>
#include "Stack.h" // Stack class definition
using namespace std;
int main() {
Stack<int> intStack; // create Stack of ints
cout << "processing an integer Stack" << endl;
// push integers onto intStack
for (int i{0}; i < 3; ++i) {
intStack.push(i);
intStack.printStack();
}
int popInteger; // store int popped from stack
// pop integers from intStack
while (!intStack.isStackEmpty()) {
intStack.pop(popInteger);
cout << popInteger << " popped from stack" << endl;
intStack.printStack();
}
Stack<double> doubleStack; // create Stack of doubles
double value{1.1};
cout << "processing a double Stack" << endl;
// push floating-point values onto doubleStack
for (int j{0}; j < 3; ++j) {
doubleStack.push(value);
doubleStack.printStack();
value += 1.1;
}
double popDouble; // store double popped from stack
// pop floating-point values from doubleStack
while (!doubleStack.isStackEmpty()) {
doubleStack.pop(popDouble);
cout << popDouble << " popped from stack" << endl;
doubleStack.printStack();
}
}
/*
processing an integer Stack
The list is: 0
The list is: 1 0
The list is: 2 1 0
2 popped from stack
The list is: 1 0
1 popped from stack
The list is: 0
0 popped from stack
The list is empty
processing a double Stack
The list is: 1.1
The list is: 2.2 1.1
The list is: 3.3 2.2 1.1
3.3 popped from stack
The list is: 2.2 1.1
2.2 popped from stack
The list is: 1.1
1.1 popped from stack
The list is empty
All nodes destroyed
All nodes destroyed
*/
3. Queue
//
// Created by on 2021/7/26.
//
#include "Queue.h"
#include <iostream>
using namespace std;
int main(){
Queue<int> intQueue;
for(int i{0}; i<3 ; ++i){
intQueue.enqueue(i);
intQueue.printQueue();
}
int dequeueInteger;
while(!intQueue.isQueueEmpty()){
intQueue.dequeue(dequeueInteger);
cout << dequeueInteger << " dequeued" << endl;
intQueue.printQueue();
}
cout << "************************;" << endl;
Queue<double> doubleQueue;
double value{1.1};
for (double j{0}; j<3; ++j){
doubleQueue.enqueue(value);
doubleQueue.printQueue();
value += j;
}
double dequeueDouble;
while(!doubleQueue.isQueueEmpty()){
doubleQueue.dequeue(dequeueDouble);
cout << dequeueDouble << " dequeued" << endl;
doubleQueue.printQueue();
}
}
/*
(base) ➜ build ./bin/list_demo
The list is: 0
The list is: 0 1
The list is: 0 1 2
0 dequeued
The list is: 1 2
1 dequeued
The list is: 2
2 dequeued
The list is empty
************************;
The list is: 1.1
The list is: 1.1 1.1
The list is: 1.1 1.1 2.1
1.1 dequeued
The list is: 1.1 2.1
1.1 dequeued
The list is: 2.1
2.1 dequeued
The list is empty
All nodes destroyed
All nodes destroyed
*/
4. Tree & TreeNode & TestTree -> 简单的递归
TreeNode.h
#ifndef BASE_CPP_TREENODE_H
#define BASE_CPP_TREENODE_H
template<typename NODETYPE>
class Tree;
template<typename NODETYPE>
class TreeNode {
friend class Tree<NODETYPE>;
public:
TreeNode(const NODETYPE &d) : data{d} {}
NODETYPE getData() const { return data; }
private:
NODETYPE data;
TreeNode<NODETYPE> *rightPtr{nullptr};
TreeNode<NODETYPE> *leftPtr{nullptr};
};
#endif //BASE_CPP_TREENODE_H
Tree.h
#ifndef BASE_CPP_TREE_H
#define BASE_CPP_TREE_H
#include <iostream>
#include "TreeNode.h"
using namespace std;
template<typename NODETYPE>
class Tree {
public:
// insert node in Tree
void insertNode(const NODETYPE &value) {
insertNodeHelper(&rootPtr, value);
}
// begin preorder traversal of Tree
void preOrderTraversal() const {
preOrderHelper(rootPtr);
}
// begin inorder traversal of Tree
void inOrderTraversal() const {
inOrderHelper(rootPtr);
}
// begin postorder traversal of Tree
void postOrderTraversal() const {
postOrderHelper(rootPtr);
}
private:
TreeNode<NODETYPE> *rootPtr{nullptr};
// 这里有点二叉搜索树的策略,左根值<中间<右根值
void insertNodeHelper(TreeNode<NODETYPE> **ptr, const NODETYPE &value) {
if (*ptr == nullptr) { // subtree is empty
*ptr = new TreeNode<NODETYPE>(value);
} else { // subtree is not empty
if (value < (*ptr)->data) {
insertNodeHelper(&((*ptr)->leftPtr), value);
} else {
if (value > (*ptr)->data) {
insertNodeHelper(&((*ptr)->rightPtr), value);
} else {
cout << value << " dup" << endl;
}
}
}
}
void preOrderHelper(TreeNode<NODETYPE>* ptr) const {
if (ptr != nullptr) {
cout << ptr->data << " ";
preOrderHelper(ptr->leftPtr);
preOrderHelper(ptr->rightPtr);
}
}
void inOrderHelper(TreeNode<NODETYPE>* ptr) const {
if (ptr != nullptr) {
inOrderHelper(ptr->leftPtr);
cout << ptr->data << " ";
inOrderHelper(ptr->rightPtr);
}
}
void postOrderHelper(TreeNode<NODETYPE>* ptr) const {
if (ptr != nullptr) {
postOrderHelper(ptr->leftPtr);
postOrderHelper(ptr->rightPtr);
cout << ptr->data << " ";
}
}
};
#endif //BASE_CPP_TREE_H
TestTree.cpp
#include <iostream>
#include <iomanip>
#include "Tree.h"
using namespace std;
int main() {
Tree<int> intTree;
cout << "Enter 10 integer values:\n";
for (int i{0}; i < 10; ++i){
int intValue = 0;
cin >> intValue;
intTree.insertNode(intValue);
}
cout << "\nPreorder traversal\n";
intTree.preOrderTraversal();
cout << "\nInorder traversal\n";
intTree.inOrderTraversal();
cout << "\nPostorder traversal\n";
intTree.postOrderTraversal();
}
/*
(base) ➜ build ./bin/list_demo
Enter 10 integer values:
50
25
75
12
33
67
88
6
13
68
Preorder traversal
50 25 12 6 13 33 75 67 68 88
Inorder traversal
6 12 13 25 33 50 67 68 75 88
Postorder traversal
6 13 12 33 25 68 67 88 75 50 %
*
*/