树的数据结构相对来说也比较好理解。但由于为了查询效率和存储效率,又有多种树形结构,对树进行了限制。
如二叉树,平衡二叉树,红黑树,B树,B+树。其实也没多少多复杂,只是愿不愿意花时间去研究。个人花了点花时间回顾了一下平衡二叉树和二叉树的理论和实现。红黑树和B树,B+树暂时没有去研究。后续有空了再补。只是将具体的特点大概了了解了一下。
代码是关于二叉树和平衡二叉树的代码实现。
P4.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
struct TreeNode
{
int key;
int value;
int height;
TreeNode() {};
TreeNode(int k, int v)
{
key = k, value = v;
leftNode = nullptr;
rightNode = nullptr;
}
TreeNode *leftNode;
TreeNode *rightNode;
};
class P4
{
public:
P4();
~P4();
void createTree();
void createTreeByPreTree(vector<int>& preVector);
TreeNode* insertRoot(TreeNode* &node,int key, int v);
vector<TreeNode*> findLastNode(TreeNode* parent, TreeNode * node);
int findPathHeigh(TreeNode *root,TreeNode *end);
void preVisit(TreeNode* node);
void mindVisit(TreeNode *node);
void endVisit(TreeNode* node);
int height(TreeNode *node);
TreeNode* leftRotation(TreeNode* node);
TreeNode* rightRotation(TreeNode*node);
TreeNode* leftRightRotation(TreeNode *node);
TreeNode* rightLeftRotation(TreeNode* node);
/*从某个节点上删除指定key的节点,并返回最终的树的根节点*/
TreeNode* remove(TreeNode*&node,int key);
TreeNode *getMaxNode(TreeNode *node);
TreeNode *getMinNode(TreeNode *node);
private:
TreeNode* m_root;
int m_hegiht;
};
P4.cpp
#include "P4.h"
P4::P4()
{
createTree();
insertRoot(m_root,1, 0);
insertRoot(m_root,2,121);
insertRoot(m_root, 3, 111);
insertRoot(m_root, 19, 11);
insertRoot(m_root, 9, 10);
insertRoot(m_root, 12, 21);
insertRoot(m_root, 6, 9);
remove(m_root,1);
cout << endl;
endVisit(m_root);
remove(m_root, 2);
cout << endl;
endVisit(m_root);
//vector<int> preVector;
//preVector.push_back(3);
//preVector.push_back(1);
//preVector.push_back(0);
//preVector.push_back(2);
//preVector.push_back(12);
//preVector.push_back(9);
//preVector.push_back(6);
//preVector.push_back(19);
preVector.push_back();
//createTreeByPreTree(preVector);
}
P4::~P4()
{
}
void P4::createTree()
{
TreeNode * root = new TreeNode(0, 0);
m_root = root;
}
void P4::createTreeByPreTree(vector<int>& preVector)
{
TreeNode * root = new TreeNode(preVector[0], 0);
m_root = root;
for (int i=1;i!=preVector.size ();++i)
{
insertRoot(m_root,preVector[i],i);
}
preVisit(m_root);
}
TreeNode* P4::insertRoot(TreeNode*&node,int key, int v)
{
if (node == nullptr)
{
node = new TreeNode(key,v);
}
else if (key < node->key)
{
node->leftNode = insertRoot(node->leftNode, key, v);
int lh = height(node->leftNode);
int rh = height(node->rightNode);
if (abs(lh - rh) == 2)
{
if (key > node->leftNode->key)
{
node = leftRightRotation(node);
}
else
{
node = rightRotation(node);
}
}
}
else if (key > node->key)
{
node->rightNode = insertRoot(node->rightNode, key, v);
int lh = height(node->leftNode);
int rh = height(node->rightNode);
if (abs(lh - rh) == 2)
{
if (key > node->rightNode->key)
{
node = leftRotation(node);
}
else
{
node = rightLeftRotation(node);
}
}
}
int leftH = height(node->leftNode);
int right = height(node->rightNode);
node->height = right > leftH ? right+1 : leftH+ 1;
return node;
}
TreeNode* P4::leftRotation(TreeNode* node)
{
/*
左旋是在右节点中插入右节点,导致失衡时需要调用的调整方法
其实就是将自己的右节点,置为自己右节点孩子的左节点,再把自己与原本自己的右节点的左节点设为自己
然后将自己的右子树赋值给自己
一次插入,2,6,插入之后,依次检查高度时,发现,0节点的子树不平衡了。
由于平衡二叉树的概念是,每个节点的左右子树的高度差的最大值的绝对值<=1
也就是要么左子树比右子树高1,有么右子树比左子树高1,要么一样高。
0
\
2
\
6
*/
TreeNode*nodeRight = node->rightNode;
node->rightNode = nodeRight->leftNode;
nodeRight->leftNode = node;
node->height = height(node);
nodeRight->height = height(nodeRight);
return nodeRight;
}
TreeNode* P4::rightRotation(TreeNode*node)
{
TreeNode *nodeLeft = node->leftNode;
node->leftNode = nodeLeft->rightNode;
nodeLeft->rightNode = node;
node->height = height(node);
nodeLeft->height = height(nodeLeft);
return nodeLeft;
}
TreeNode* P4::leftRightRotation(TreeNode *node)
{
node->leftNode = leftRotation(node->leftNode);
node = rightRotation(node);
return node;
}
TreeNode* P4::rightLeftRotation(TreeNode* node)
{
node->rightNode = rightRotation(node->rightNode);
node = leftRotation(node);
return node;
}
void P4::preVisit(TreeNode* node)
{
if (node != NULL)
{
cout << node->key << endl;
preVisit(node->leftNode);
preVisit(node->rightNode);
}
}
void P4::mindVisit(TreeNode *node)
{
if (node != NULL)
{
mindVisit(node->leftNode);
cout << node->key << endl;
mindVisit(node->rightNode);
}
}
void P4::endVisit(TreeNode* node)
{
if (node != NULL)
{
endVisit(node->leftNode);
endVisit(node->rightNode);
cout << node->key << endl;
}
}
int P4::height(TreeNode *node)
{
if (node != nullptr)
{
int left = height(node->leftNode);
int right = height(node->rightNode);
if (left < right)
{
return right + 1;
}
else
{
return left + 1;
}
}
else
{
return 0;
}
}
/*从某个节点上删除指定key的节点,并返回最终的树的根节点*/
TreeNode* P4::remove(TreeNode*&node, int key)
{
/*
找不到key,则根据左右值向下递归查找。
如果node为null,返回 NULL;
否则,根据key值大小,向左向右查找。
当找到key时,分五种情况。
1 此节点没有子节点,可以直接删除
2 此节点有一个子节点,用子节点取代自己,并删除子节点
3 如果有两个节点,需要找出取代当前节点的节点。如果左节点不为空,从左节点中查找最大的节点用来取代。
如果右节点不为空,找出右节点中最小的节点取代
*/
if (node != nullptr)
{
if (key == node->key)
{
if (node->rightNode != nullptr &&node->leftNode != nullptr)
{
if (height(node->rightNode) < height(node->leftNode))
{
TreeNode * minNode = getMinNode(node->rightNode);
node->key = minNode->key;
node->rightNode = remove(node->rightNode, node->key);
}
else
{
TreeNode * maxNode = getMaxNode(node->leftNode);
node->key = maxNode->key;
node->leftNode = remove(node->leftNode, node->key);
}
}
else
{
TreeNode *pre = node;
if (node->leftNode != nullptr)
{
node = node->leftNode;
}
if (node->rightNode != nullptr)
{
node = node->rightNode;
}
delete(pre);
return nullptr;
}
}
else if (key > node->key)
{
node->rightNode = remove(node->rightNode, key);
int lH = height(node->rightNode);
int rH = height(node->leftNode);
if (abs(lH - rH) == 2)
{
int llh = height(node->leftNode->leftNode);
int lrh = height(node->leftNode->rightNode);
if (llh > lrh)
{
node = leftRightRotation(node);
}
else
{
node = rightRotation(node);
}
}
}
else if (key < node->key)
{
node->leftNode = remove(node->leftNode, key);
int lH = height(node->leftNode);
int rH = height(node->rightNode);
if (abs(lH - rH) == 2)
{
int rlH = height(node->rightNode->leftNode);
int rrh = height(node->rightNode->rightNode);
if (rlH > rrh)
{
node = rightLeftRotation(node);
}
else
{
node = leftRotation(node);
}
}
}
return node;
}
return nullptr;
}
TreeNode *P4::getMaxNode(TreeNode *node)
{
if (node->rightNode != nullptr)
{
return getMaxNode(node->rightNode);
}
return node;
}
TreeNode *P4::getMinNode(TreeNode *node)
{
if (node->leftNode != nullptr)
{
return getMinNode(node->leftNode);
}
return node;
}