抽象类:接口类,不能实例化类,派生类必须重写函数才能使用。
class Car
{
public:
//纯虚函数
virtual void Drive() = 0;
};
class Benz :public Car
{
public:
virtual void Drive()
{
cout << "Benz" << endl;
}
};
Benz重写后才能实例化,本质上抽象类是为了强制重写
静态成员函数不能是虚函数,没有this指针,不能通过虚表调用
构造函数不能是虚函数,虚表是在编译时生成,虚表在初始化列表才有,调用构造函数,会在虚表生成前,析构函数是虚函数。
虚函数调用慢于普通函数和内联函数。
虚函数表在编译阶段生成,存在代码端
菱形继承是数据冗余和二义性。
搜索二叉树:BST
左节点<根节点<右节点
template<class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key)
:_left(nullptr)
,_right(nullptr)
,_key(key)
{
}
};
template<class K>
class BSTree
{
typedef BSTreeNode<K> Node;
public:
BSTree()
:_root(nullptr)
{
}
bool Insert(const K& key)
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
cur = new Node(key);
if (parent->_key < key)
{
parent->_right = cur;
}
else
{
parent->_left = cur;
}
return true;
}
bool Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
cur = cur->_right;
}
else if (cur->_key > key)
{
cur = cur->_left;
}
return false;
}
}
bool Erase(const K& key)
{
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
else //找到了
{
// 左为空
if (cur->_left ==nullptr)
{
if (cur == _root)
{
_root = cur->_right;
}
else
{
if (parent->_right == cur)
{
parent->_right = cur->_right;
}
else
{
parent->_left = cur->_right;
}
}
}
// 右为空
else if (cur->_right == nullptr)
{
if (cur == _root)
{
_root = cur->_left;
}
else{
if (parent->_right == cur)
{
parent->_right = cur->_left;
}
else
{
parent->_left = cur->_left;
}
}
}
else
{
Node* parent = cur;
Node* leftMax = cur->_left;
while (leftMax->_right)
{
parent = leftMax;
leftMax = leftMax->_right;
}
swap(cur->_key, leftMax->_key);
if (parent->_left == leftMax)
{
parent->_left = leftMax->_left;
}
else
{
parent->_right = leftMax->_left;
}
cur = leftMax;
}
delete cur;
return true;
}
}
return false;
}
void InOrder()
{
_InOrder(_root);
}
void _InOrder(Node* root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
std::cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root;
};
void TestBSTree1()
{
int a[] = { 8,3,1,10,6,4,7,14,13 };
BSTree<int> t;
for (auto e : a)
{
t.Insert(e);
}
t.InOrder();
t.Erase(6);
printf("\n");
t.InOrder();
}
搜索二叉树递归版
#include<iostream>
using namespace std;
template<typename T>
struct BSTreeNode
{
// 引用是为了value对像是自定义结构体,防止深拷贝
BSTreeNode(const T& value)
:_left(nullptr)
,_right(nullptr)
,_value(value)
{
}
BSTreeNode<T>* _left;
BSTreeNode<T>* _right;
T _value;
};
template<typename T>
class BSTree
{
typedef BSTreeNode<T> Node;
public:
BSTree()
:root(nullptr)
{
}
BSTree(const BSTree<T>& s)
{
root=Copy(root,s.root);
}
~BSTree()
{
Destory(root);
}
bool Insert(const T& value)
{
if (root == nullptr)
{
root = new Node(value);
return true;
}
Node* cur = root;
Node* before = root;
while (cur)
{
if (value>cur->_value)
{
before = cur;
cur = cur->_right;
}
else if (value < cur->_value)
{
before = cur;
cur = cur->_left;
}
else
{
return false;
}
}
//找到空的位置,区分是在左还是右
// 比较值也可以
if (before->_right)
{
// 左为空
before->_left = new Node(value);
}
else if (before->_left)
{
// 右为空,左不为空
before->_right = new Node(value);
}
else
{
// 左右都为空
if (value > before->_value)
{
// 放在右边
before->_right = new Node(value);
}
else
{
before->_left = new Node(value);
}
}
return true;
}
bool InsertR(const T& value)
{
return _InsertR(root, value);
}
bool FindR(const T& value)
{
return _FindR(root, value);
}
bool Find(const T& value)
{
Node* cur = root;
while(cur)
{
if (value < cur->_value)
{
cur = cur->_left;
}
else if (value>cur->_value)
{
cur=cur->_right;
}
else
{
return true;
}
}
return false;
}
bool EraseR(const T& value)
{
return _EraseR(root, value);
}
bool Erase(const T& value)
{
Node* before = root;
Node* cur = root;
while (cur)
{
if (cur->_value < value)
{
before = cur;
cur = cur->_right;
}
else if (cur->_value > value)
{
before = cur;
cur = cur->_left;
}
else
{
// 分为左右为空
if (!cur->_left && !cur->_right)
{
// 判断节点是左还是右
//节点为左
if (before->_left==cur)
{
before->_left = nullptr;
}
else
{
before->_right = nullptr;
}
}
// 分为左为空,右不为空
else if (!cur->_left&&cur->_right)
{
Node* next = cur->_right;
if (before->_left == cur)
{
before->_left = next;
}
else
{
before->_right = next;
}
}
// 右为空,左不为空
else if(cur->_left&&!cur->_right)
{
Node* next = cur->_left;
if (before->_left == cur)
{
before->_left = next;
}
else
{
before->_right = next;
}
}
else
{
//两边非空都,找左树的最大值右或者右树的最大值
Node* pos = cur;
Node* left_max = cur->_left;
while(left_max->_right)
{
cur = left_max;
left_max = left_max->_right;
}
swap(left_max->_value, pos->_value);
//第一个左节点构成左树
if (cur->_left == left_max)
{
cur->_left = left_max->_left;
}
else
{
cur->_right = left_max->_left;
}
// 把cur强行定义为要释放的值
cur = left_max;
}
delete cur;
return true;
}
}
return false;
}
void InOrder()
{
_InOrder(root);
printf("\n");
}
private:
// 递归返回
Node* Copy(Node* root,Node* root1)
{
if (root1 == nullptr)
{
return nullptr;
}
root = new Node(root1->_value);
root->_left = Copy(root,root1->_left);
root->_right = Copy(root,root1->_right);
return root;
}
// 递归释放空间
void Destory(Node* root)
{
if (root == nullptr)
{
return;
}
Destory(root->_left);
Destory(root->_right);
delete root;
return;
}
bool _EraseR(Node*& root, const T& value)
{
if (root == nullptr)
{
return false;
}
if (value >root->_value)
{
return _EraseR(root->_right, value);
}
else if (value < root->_value)
{
return _EraseR(root->_left, value);
}
else
{
Node* leftmax = root->_left;
if (leftmax == nullptr)
{
Node* del = root;
root = nullptr;
delete del;
return true;
}
while (leftmax->_right)
{
leftmax = leftmax->_right;
}
swap(root->_value, leftmax->_value);
// 只取左树依然是符号树的规律
return _EraseR(root->_left, value);
}
}
bool _InsertR(Node*& root, const T& value)
{
if (root == nullptr)
{//传引用使得可以直接赋值
// 当要修改某个节点,且这个操作不是递归操作
root = new Node(value);
return true;
}
if (value < root->_value)
{
return _InsertR(root->_left, value);
}
else if(root->_value<value)
{
return _InsertR(root->_right,value);
}
else
{
return false;
}
}
bool _FindR(Node* root, const T& value)
{
if (root == nullptr)
{
return false;
}
if (value < root->_value)
{
return _FindR(root->_left, value);
}
else if(value>root->_value)
{
return _FindR(root->_right, value);
}
else
{
return true;
}
}
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_value;
_InOrder(root->_right);
}
Node* root;
};