Commit c7c5fe1f authored by xep's avatar xep
Browse files
parents 489f66c6 d496c4e0
#include <iostream>
#include <utility>
#include <stdint.h>
/// <summary>
/// 2021.06.03
/// 标准二叉搜索树。暂不考虑数据域
/// </summary>
template <typename K>
class BST {
public:
struct BSTNode {
K key;
BSTNode* left, * right;
BSTNode(const K& k) :key(k), left(nullptr), right(nullptr) {}
};
BST() :root(nullptr) {}
BST(const BST& t);
BST(BST&& t);
~BST();
BST& operator=(const BST& t);
BST& operator=(BST&& t);
const BSTNode* get_insert_parent(const K& key)const;
const BSTNode* find_parent(const K& key)const;
BSTNode* insert(const K& key);
BSTNode* find(const K& key);
inline const BSTNode* find(const K& key)const {
return const_cast<BST*>(this)->find(key);
}
BSTNode* copy()const;
inline const BSTNode* get_root()const {
return root;
}
private:
BSTNode* root;
BSTNode* copy_nodes(const BSTNode* r)const;
void destruct_node(BSTNode* r);
const BSTNode* get_insert_parent(const K& key, const BSTNode* n)const;
const BSTNode* find_parent(const K& key, const BSTNode* n)const;
BSTNode* insert(const K& key, BSTNode* n);
BSTNode* find(const K& key, BSTNode* n);
};
template<typename K>
BST<K>::BST(const BST<K>& t) :root(t.copy())
{
}
template<typename K>
BST<K>::BST(BST&& t) : root(t.root)
{
t.root = nullptr;
}
template<typename K>
BST<K>::~BST()
{
destruct_node(root);
root = nullptr;
}
template<typename K>
BST<K>& BST<K>::operator=(const BST& t)
{
root = t.copy();
return *this;
}
template<typename K>
BST<K>& BST<K>::operator=(BST&& t)
{
root = t.root;
t.root = nullptr;
}
template<typename K>
const typename BST<K>::BSTNode* BST<K>::get_insert_parent(const K& key) const
{
return get_insert_parent(key, root);
}
template<typename K>
const typename BST<K>::BSTNode* BST<K>::find_parent(const K& key) const
{
return find_parent(key, root);
}
template<typename K>
typename BST<K>::BSTNode* BST<K>::insert(const K& key)
{
if (!root) {
root = new BSTNode(key);
return root;
}
return insert(key, root);
}
template<typename K>
typename BST<K>::BSTNode* BST<K>::find(const K& key)
{
return find(key, root);
}
template<typename K>
typename BST<K>::BSTNode* BST<K>::copy() const
{
return copy_nodes(root);
}
template<typename K>
typename BST<K>::BSTNode* BST<K>::copy_nodes(const BSTNode* r) const
{
if (!r)
return nullptr;
auto* n = new BSTNode(r->key);
n->left = copy_nodes(r->left);
n->right = copy_nodes(r->right);
return n;
}
template<typename K>
void BST<K>::destruct_node(BSTNode* r)
{
if (!r)
return;
destruct_node(r->left);
destruct_node(r->right);
delete r;
}
\ No newline at end of file
......@@ -7,3 +7,5 @@ Implementation of classic data structure and some algorithm for OJ of Data Struc
一些数据结构仅根据要求实现了部分功能;有的功能不允许操作或者声明了函数而没写实现。
注意编译器必须支持`C++11`标准。
/// <summary>
/// 2021.06.03 带附加头结点的单向链表
/// 参考std::forward_list 设计API
/// </summary>
template <typename T>
class ForwardList {
public:
struct Node {
T data;
Node* next;
Node(const T& d) :data(d), next(nullptr) {}
Node() :data(), next(nullptr) {}
};
private:
Node head;
public:
ForwardList() = default;
ForwardList(const ForwardList& lst);
ForwardList(ForwardList&& lst);
~ForwardList();
ForwardList& operator=(const ForwardList& lst);
ForwardList& operator=(ForwardList&& lst);
void push_front(const T& data);
void remove_after(Node* node);
void insert_after(Node* node, const T& data);
void clear();
int get_size()const;
inline Node* before_begin() {
return &head;
}
inline const Node* before_begin()const {
return &head;
}
inline Node* begin() {
return head.next;
}
inline const Node* begin()const {
return head.next;
}
inline bool empty()const {
return head.next == nullptr;
}
//返回一个删除了指定节点的副本
ForwardList remove_copy(const Node* node)const;
void show()const;
private:
//附加头结点
Node* copy_nodes()const;
};
template<typename T>
ForwardList<T>::ForwardList(const ForwardList& lst)
{
head.next = lst.copy_nodes();
}
template<typename T>
ForwardList<T>::ForwardList(ForwardList&& lst)
{
head.next = lst.head.next;
lst.head.next = nullptr;
}
template<typename T>
ForwardList<T>::~ForwardList()
{
clear();
}
template<typename T>
ForwardList<T>& ForwardList<T>::operator=(const ForwardList& lst)
{
head.next = lst.copy_nodes();
return *this;
}
template<typename T>
ForwardList<T>& ForwardList<T>::operator=(ForwardList&& lst)
{
head.next = lst.head.next;
lst.head.next = nullptr;
return *this;
}
template<typename T>
void ForwardList<T>::push_front(const T& data)
{
auto* node = new Node(data);
node->next = head.next;
head.next = node;
}
template<typename T>
void ForwardList<T>::remove_after(Node* node)
{
if (!node || !(node->next))
return;
auto* tmp = node->next;
node->next = node->next->next;
delete tmp;
}
template<typename T>
void ForwardList<T>::insert_after(Node* node, const T& data)
{
if (!node)
return;
auto* n = new Node(data);
n->next = node->next;
node->next = n;
}
template<typename T>
void ForwardList<T>::clear()
{
if (!head.next)
return;
auto* p0 = head.next;
auto* p1 = head.next->next;
while (p1) {
p1 = p1->next;
delete p0;
p0 = p1;
}
delete p0;
head.next = nullptr;
}
template<typename T>
int ForwardList<T>::get_size() const
{
auto* p = head.next;
int n = 0;
for (; p; p = p->next)
n++;
return n;
}
template<typename T>
ForwardList<T> ForwardList<T>::remove_copy(const Node* node)const
{
ForwardList<T> res;
Node* n = &(res.head);
auto* p = head.next;
for (; p; p = p->next) {
if (p == node) {
p = p->next;
if (!p)break;
}
n->next = new Node(p->data);
n = n->next;
}
return res;
}
template<typename T>
void ForwardList<T>::show() const
{
std::cout << "[ ";
for (auto* p = head.next; p; p = p->next) {
std::cout << p->data << ", ";
}
std::cout << " ]" << std::endl;
}
//不包含头结点
template<typename T>
typename ForwardList<T>::Node* ForwardList<T>::copy_nodes() const
{
if (!head.next)
return nullptr;
Node* n = new Node(head.next->data);
Node* n0 = n;
auto* p = head.next->next;
for (; p; p = p->next) {
n->next = new Node(p->data);
n = n->next;
}
return n0;
}
\ No newline at end of file
/**
* 使用邻接矩阵表示的有向图。
*/
#include <iostream>
#include <utility>
#include <limits>
/**
* 二维数组的简单封装,使用连续空间,运算下标
*/
template <typename T>
class Matrix {
int row, col;
T* data;
public:
Matrix(int row_, int col_);
~Matrix();
T& get(int i, int j);
T* get_pointer(int i, int j);
inline T* get_pointer_serial(int n) {
return data + n;
}
inline const T& get(int i, int j)const {
return const_cast<Matrix*>(this)->get(i, j);
}
inline int get_row()const {
return row;
}
inline int get_col()const {
return col;
}
void fill(const T& d);
Matrix(const Matrix&) = delete;
Matrix(Matrix&&) = delete;
Matrix& operator=(const Matrix&) = delete;
Matrix& operator=(Matrix&&) = delete;
void show()const;
};
template<typename T>
Matrix<T>::Matrix(int row_, int col_) :row(row_), col(col_)
{
data = new T[row * col];
}
template<typename T>
Matrix<T>::~Matrix()
{
delete[] data;
data = nullptr;
}
template<typename T>
T& Matrix<T>::get(int i, int j)
{
return data[i * col + j];
}
template<typename T>
T* Matrix<T>::get_pointer(int i, int j)
{
return data + i * col + j;
}
template<typename T>
void Matrix<T>::fill(const T& d)
{
std::fill(data, data + row * col, d);
}
template<typename T>
void Matrix<T>::show() const
{
std::cout << '[' << std::endl;
for (int i = 0; i < row; i++) {
std::cout << ' ';
for (int j = 0; j < col; j++) {
std::cout << get(i, j) << ' ';
}
std::cout << std::endl;
}
std::cout << ']' << std::endl;
}
/// <summary>
/// 2021.06.03
/// 邻接矩阵表示的图
/// </summary>
template <typename E>
class MatGraph {
Matrix<E> mat;
int size;
public:
static constexpr E MAX = std::numeric_limits<E>::max()-1;
MatGraph(int size_);
//冲突时只保留最短边
void add_edge(int u, int v, const E& data);
void add_biedge(int u, int v, const E& data);
inline int get_edata(int u, int v)const {
return mat.get(u, v);
}
//-1表示不存在
int first_neigh(int u)const;
int next_neigh(int u, int v)const;
inline int get_size()const {
return size;
}
};
template<typename E>
MatGraph<E>::MatGraph(int size_): size(size_), mat(size_, size_)
{
mat.fill(MAX);
for (int i = 0; i < size; i++) {
mat.get(i, i) = 0;
}
}
template<typename E>
void MatGraph<E>::add_edge(int u, int v, const E& data)
{
mat.get(u, v) = std::min(mat.get(u, v), data);
}
template<typename E>
void MatGraph<E>::add_biedge(int u, int v, const E& data)
{
add_edge(u, v, data);
add_edge(v, u, data);
}
template<typename E>
int MatGraph<E>::first_neigh(int u) const
{
for (int j = 0; j < size; j++) {
if (mat.get(u, j) < MAX)
return j;
}
return -1;
}
template<typename E>
int MatGraph<E>::next_neigh(int u, int v) const
{
if (v == -1)
return -1;
for (int j = v + 1; j < size; j++) {
if (mat.get(u, j) < MAX)
return j;
}
return -1;
}
using G = MatGraph<int16_t>;
inline int get_min(const bool* si, const int* dist, const int n) {
int mi = -1, ms = G::MAX;
for (int i = 0; i < n; i++) {
if (!si[i]) {
if (dist[i] < ms) {
ms = dist[i];
mi = i;
}
}
}
return mi;
}
/**
* 基于邻接矩阵的Dijkstra算法的实现
*/
int sssp(const G& graph)
{
int n = graph.get_size();
bool* si = new bool[n];
int* dist = new int[n];
std::fill(si, si + n, false);
std::fill(dist, dist + n, G::MAX);
dist[0] = 0;
for (int cnt = 0; cnt < n; cnt++) {
int mi = get_min(si, dist, n);
if (mi == -1 || dist[mi] == G::MAX) {
//没有可达的了,再见
break;
}
si[mi] = true;
int mj = graph.first_neigh(mi);
for (; mj!=-1; mj=graph.next_neigh(mi,mj)) {
dist[mj] = std::min(dist[mj], dist[mi] + graph.get_edata(mi,mj));
}
}
if (dist[n - 1] == G::MAX)
return -1;
else return dist[n - 1];
}
#include <iostream>
#include <utility>
/**
* 二维数组的简单封装,使用连续空间,运算下标
*/
template <typename T>
class Matrix {
int row, col;
......@@ -16,6 +10,12 @@ public:
inline T* get_pointer_serial(int n) {
return data + n;
}
inline T& get_serial(int n) {
return *(data + n);
}
inline int get_size()const {
return row * col;
}
inline const T& get(int i, int j)const {
return const_cast<Matrix*>(this)->get(i, j);
}
......@@ -25,6 +25,10 @@ public:
inline int get_col()const {
return col;
}
inline int index_to_serial(int i, int j)const {
return i * col + j;
}
void index_to_rowcol(int n, int& i, int& j)const;
void fill(const T& d);
Matrix(const Matrix&) = delete;
......@@ -36,7 +40,7 @@ public:
};
template<typename T>
Matrix<T>::Matrix(int row_, int col_):row(row_),col(col_)
Matrix<T>::Matrix(int row_, int col_) :row(row_), col(col_)
{
data = new T[row * col];
}
......@@ -60,6 +64,13 @@ T* Matrix<T>::get_pointer(int i, int j)
return data + i * col + j;
}
template<typename T>
void Matrix<T>::index_to_rowcol(int n, int& i, int& j) const
{
j = n % col;
i = n / col; //int div
}
template<typename T>
void Matrix<T>::fill(const T& d)
{
......@@ -78,4 +89,28 @@ void Matrix<T>::show() const
std::cout << std::endl;
}
std::cout << ']' << std::endl;
}
//以下:四邻域判定
using MI = Matrix<int>;
//using MD = Matrix<std::array<int, 4>>;
using namespace std;
//方向指标:0,1,2,3 上下左右
inline void get_dir(int dir, int& dx, int& dy) {
switch (dir) {
case 0:dx = 0; dy = 1; return;
case 1:dx = 0, dy = -1; return;
case 2:dx = -1; dy = 0; return;