创作过程中难免有不足,若您发现本文内容有误,恳请不吝赐教。
一、优先级队列
1.大堆
#include<iostream>
#include<queue>
using namespace std;
int main()
{
priority_queue<int> q;
//priority_queue<int, vector<int>, less<int>> q;
q.push(8);
q.push(6);
q.push(4);
q.push(9);
while (!q.empty())
{
cout << q.top() << " ";
q.pop();
}
cout << endl;
return 0;
}
2.小堆
#include<iostream>
#include<queue>
using namespace std;
int main()
{
priority_queue<int,vector<int>,greater<int>> q;
q.push(8);
q.push(6);
q.push(4);
q.push(9);
while (!q.empty())
{
cout << q.top() << " ";
q.pop();
}
cout << endl;
return 0;
}
二、二叉搜索树
1.下面操作采用循环的方式
①创建和中序遍历
//Test.cpp
#include"BinarySearchTree.h"
int main()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> bt;
for (auto e : a)
bt.Insert(e);
bt._InOrder();
return 0;
}
//BinarySearchTree.h
#pragma once
#include<iostream>
using namespace std;
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:
bool Insert(const K& key)
{
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
parent = cur;
if (cur->_key < key)
cur = cur->right;
else if (cur->_key > key)
cur = cur->left;
else
return false;
}
cur = new Node(key);
if (parent->_key > key)
parent->left = cur;
else
parent->right = cur;
return false;
}
void _InOrder(Node* root)
{
if (root == nullptr)
return;
_InOrder(root->left);
cout << root->_key << " ";
_InOrder(root->right);
}
void _InOrder()
{
_InOrder(_root);
cout << endl;
}
private:
Node* _root = nullptr;
};
②查找
//Test.cpp
#include"BinarySearchTree.h"
int main()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> bt;
for (auto e : a)
bt.Insert(e);
bt._InOrder();
cout << bt.Find(1) << endl;
return 0;
}
//BinarySearchTree.h
bool Find(const K& key)
{
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
cur = cur->left;
else if (cur->_key < key)
cur = cur->right;
else
return true;
}
return false;
}
③删除
//Test.cpp
#include"BinarySearchTree.h"
int main()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> bt;
for (auto e : a)
bt.Insert(e);
bt._InOrder();
bt.Erase(14);
bt._InOrder();
bt.Erase(3);
bt._InOrder();
bt.Erase(8);
bt._InOrder();
return 0;
}
//BinarySearchTree.h
bool Erase(const K& key)
{
Node* parent = nullptr;
Node* cur = _root;
while (cur)
{
if (cur->_key > key)
{
parent = cur;
cur = cur->left;
}
else if (cur->_key < key)
{
parent = cur;
cur = cur->right;
}
else
{
// 准备删除
if (cur->left == nullptr)
{//左为空,有两种情况
if (cur == _root)
_root = cur->right;
else
{
//节点在整个树的左子树
if (cur == parent->left)
parent->left = cur->right;
//节点在整个树的右子树
else
parent->right = cur->right;
}
delete cur;
}
else if (cur->right == nullptr)
{//右为空
if (cur == _root)
_root = cur->left;
else
{
//节点在整个树的左子树
if (cur == parent->left)
parent->left = cur->left;
//节点在整个树的右子树
else
parent->right = cur->left;
}
delete cur;
}
else
{//左右都不为空
// 右树的最小节点(最左节点)
Node* parent = cur;
//Node* parent = nullptr;不要这样写,会出现空指针的问题
Node* subleft = cur->right;
while (subleft->left)
{
parent = subleft;
subleft = subleft->left;
}
swap(cur->_key, subleft->_key);
if (subleft == parent->left)
parent->left = subleft->right;
else
parent->right = subleft->right;
delete subleft;
}
return true;
}
}
return false;
}
2.下面操作采用递归的方式(推荐)
以_InOrder()为例解释public下的_InOrder()和private下的_InOrder(Node* root):主函数处调用下面的_InOrder(),然后_InOrder()调用private的_InOrder(Node* root) .
①创建和中序遍历
//BinarySearchTree.h
#pragma once
#include<iostream>
using namespace std;
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:
void _InOrder()
{
_InOrder(_root);
cout << endl;
}
bool InsertR(const K& key)
{
return _InsertR(_root, key);
}
private:
Node* _root = nullptr;
void _InOrder(Node* root)
{
if (root == nullptr)
return;
_InOrder(root->left);
cout << root->_key << " ";
_InOrder(root->right);
}
bool _InsertR(Node*& root, const K& key)
{//不能写成bool _InsertR(Node*& root, const K & key),加上&取别名来链接插入的节点
//别名作用:实则指向的是要插入节点的父节点
if (root == nullptr)
{
root = new Node(key);
return true;
}
if (root->_key > key)
return _InsertR(root->left, key);
else if (root->_key < key)
return _InsertR(root->right, key);
else
return false;
}
};
//Test.cpp
#include"BinarySearchTree.h"
int main()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> bt;
for (auto e : a)
bt.InsertR(e);
bt._InOrder();
return 0;
}
②查找
class BSTree
{
typedef BSTreeNode<K> Node;
public:
bool FindR(const K& key)
{
return _FindR(_root, key);
}
private:
Node* _root = nullptr;
bool _FindR(Node* root, const K& key)
{
if (root == nullptr)
return false;
if (root->_key > key)
return _FindR(root->left, key);
else if (root->_key < key)
return _FindR(root->right, key);
else
return true;
}
};
③删除
class BSTree
{
typedef BSTreeNode<K> Node;
public:
bool EraseR(const K& key)
{
return _EraseR(_root, key);
}
private:
Node* _root = nullptr;
bool _EraseR(Node*& root, const K& key)
{
if (root == nullptr)
return false;
if (root->_key > key)
return _EraseR(root->left, key);
else if (root->_key < key)
return _EraseR(root->right, key);
else
{
// 删除
if (root->left == nullptr)
{//左子树为空,此时root实则是父节点的右指向的别名
Node* del = root;
root = root->right;
delete del;
return true;
}
else if (root->right == nullptr)
{//右子树为空,此时root实则是父节点的左指向的别名
Node* del = root;
root = root->left;
delete del;
return true;
}
else
{
Node* subLeft = root->right;
while (subLeft->left)
{
subLeft = subLeft->left;
}
swap(root->_key, subLeft->_key);
// 转换成在子树去递归删除
return _EraseR(root->right, key);
}
}
}
};
④构造和析构函数
BSTree()
{
}
BSTree(const BSTree<K>& t)
{
_root = Copy(t._root);
}
~BSTree()
{
Destroy(_root);
}
private:
Node* _root = nullptr;
Node* Copy(Node* root)
{
if (root == nullptr)
return nullptr;
Node* newNoot = new Node(root->_key);
newNoot->left = Copy(root->left);
newNoot->right = Copy(root->right);
return newNoot;
}
void Destroy(Node*& root)
{
if (root == nullptr)
return;
Destroy(root->left);
Destroy(root->right);
delete root;
root = nullptr;
}
//Test.cpp
#include"BinarySearchTree.h"
int main()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> bt;
for (auto e : a)
bt.InsertR(e);
bt._InOrder();
BSTree<int> copy(bt);
copy._InOrder();
return 0;
}
⑤赋值
BSTree<K>& operator=(BSTree<K> t)
{
swap(_root, t._root);
return *this;
}
三、习题
1.数组中的第K个最大元素
//力扣代码
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int> pq(nums.begin(),nums.end());
while(--k)
{
pq.pop();
}
return pq.top();
}
};
总结
例如:以上就是今天要讲的内容,本文仅仅简单介绍了c++的基础知识。