introduction to algorithms 菜鸟笔记 sattree(统计树)

本文介绍了一种使用模板实现的红黑树数据结构。该实现支持插入、删除等基本操作,并提供了秩查询和选择操作。此外,还实现了左旋、右旋等平衡调整方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//author:yydrewdrew

#include <iostream>
using namespace std;

template <class T>
struct StatTreeNode
{
 T data;
 unsigned int size;
 StatTreeNode *parent;
 StatTreeNode *left;
 StatTreeNode *right;
 enum Color{R,B};
 Color color;
};


template <class T>
class StatTree
{
public:
 StatTreeNode<T> *Select(const int st)const;
 int Rank(const T &t)const;
 void TreeWalk()const;
 StatTreeNode<T> *Insert(const T &t);
 StatTreeNode<T> *Delete(const T &t);
 StatTreeNode<T> *Serach(const T &t)const;
 StatTreeNode<T> *Predecesor(const T &t)const;
 StatTreeNode<T> *Successor(const T &t)const;
 StatTreeNode<T> *Min()const;
 StatTreeNode<T> *Max()const;
 void Clear();
 void Swap(StatTree<T> &obj);
public:
 StatTree():root(NULL),NIL(new(StatTreeNode<T>))
 {
  NIL->data = 0;
  NIL->left = NULL;
  NIL->right = NULL;
  NIL->size = 0;
  NIL->color = StatTreeNode<T>::B;
 }
 StatTree<T> &operator = (const StatTree<T> &obj);
 StatTree<T>(const StatTree<T> &obj);
 virtual ~StatTree();
private:
 StatTree(StatTreeNode<T> *r,StatTreeNode<T> *nil):root(r),NIL(nil){}
 StatTreeNode<T> * GetSelect(int st,StatTreeNode<T> *root)const;
 void LeftRotate(StatTreeNode<T> *const p);
 void LeftRotate(const T &t);
 void RightRotate(StatTreeNode<T> *const p);
 void RightRotate(const T &t);
 void StatTreeInsertFixup(StatTreeNode<T> *p);
 void StatTreeDeleteFixup(StatTreeNode<T> *p);
 void Clean()
 {
  root = NULL;
  NIL = NULL;
 }
 void Destory(StatTreeNode<T> *p);
 void Scan(StatTreeNode<T> *root)const;
 void Copy(StatTreeNode<T> *p,const StatTree<T> &obj);
 void MaintenanceSize(StatTreeNode<T> *p);
private:
 StatTreeNode<T> *root;
 StatTreeNode<T> *NIL;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
int StatTree<T>::Rank(const T &t)const
{
 StatTreeNode<T> *p = Serach(t);
 int st = p->left->size + 1;
 while (p != root)
 {
  if (p == p->parent->right)
  {
   st = st + p->parent->left->size + 1;
  }
  p = p->parent;
 }
 return st;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Select(const int st)const
{
 return(GetSelect(st,root));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::GetSelect(int st,StatTreeNode<T> *root)const
{
 if (st <= 0)
 {
  return NULL;
 }
 int size = root->left->size + 1;
 if (st == size)
 {
  return root;
 }
 else if(st < size)
 {
  GetSelect(st,root->left);
 }
 else
 {
  GetSelect(st - size,root->right);
 }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Swap(StatTree<T> &obj)
{
 std::swap(root,obj.root);
 std::swap(NIL,obj.NIL);
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTree<T> &StatTree<T>::operator = (const StatTree<T> &obj)
{
 if (this != &obj)
 {
  Swap(StatTree<T>(obj));
 }
 return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Copy(StatTreeNode<T> *p,const StatTree<T> &obj)
{
 if (p != obj.NIL)
 {
  Copy(p->left,obj);
  Insert(p->data);
  Copy(p->right,obj);
 }
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTree<T>::StatTree(const StatTree<T> &obj)
{
 root = NULL;
 NIL = new StatTreeNode<T>;
 NIL->data = 0;
 NIL->left = NULL;
 NIL->right = NULL;
 NIL->color = StatTreeNode<T>::B;
 Copy(obj.root,obj);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Scan(StatTreeNode<T> *root)const
{
 if (root == NULL || root == NIL)
 {
  return;
 }
 Scan(root->left);
 cout<<root->data<<endl;
 Scan(root->right);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::TreeWalk()const
{
 Scan(root);
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Min()const
{
 if (root == NULL)
 {
  return NULL;
 }
 StatTreeNode<T> *p = root;
 StatTreeNode<T> *p2 = NULL;
 while (p != NIL)
 {
  p2 = p;
  p = p->left;
 }
 return p2;
}
//////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Max()const
{
 if (root == NULL)
 {
  return NULL;
 }
 StatTreeNode<T> *p = root;
 StatTreeNode<T> *p2 = NULL;
 while (p != NIL)
 {
  p2 = p;
  p = p->right;
 }
 return p2;
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Serach(const T &t)const
{
 if (root == NULL)
 {
  return NULL;
 }
 StatTreeNode<T> *p = root;
 while (p != NIL)
 {
  if (t > p->data)
  {
   p = p->right;
  }
  else if (t < p->data)
  {
   p = p->left;
  }
  else
  {
   return p;
  }
 }
 return NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Successor(const T &t)const
{
 StatTreeNode<T> *p = Serach(t);
 if (p->right != NIL)
 {
  StatTree<T> treetem(p->right,NIL);
  p = treetem.Min();
  treetem.Clean();
  return p;
 }
 StatTreeNode<T> *p2 = p->parent;
 while (p2 != NIL && p == p2->right)
 {
  p = p2;
  p2 = p2->parent;
 }
 return p2;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Predecesor(const T &t)const
{
 StatTreeNode<T> *p = Serach(t);
 if (p->left != NIL)
 {
  StatTree<T> treetem(p->left,NIL);
  p = treetem.Max();
  treetem.Clean();
  return p;
 }
 StatTreeNode<T> *p2 = p->parent;
 while (p2 != NIL && p == p2->left)
 {
  p = p2;
  p2 = p2->parent;
 }
 return p2;
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::LeftRotate(StatTreeNode<T> *const p)
{
 if (p == NULL || p == NIL)
 {
  return;
 }
 if(p->right == NIL)
 {
  return;
 }
 StatTreeNode<T> *p2 = p->right;
 p2->parent = p->parent;
 if (p->parent != NIL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = p2;
  }
  else
  {
   p->parent->right = p2;
  }
 }
 if (p2->left != NIL)
 {
  p2->left->parent = p;
 }
 p->right = p2->left;
 p2->left = p;
 p->parent = p2;
 p2->size = p->size;
 p->size = p->left->size + p->right->size + 1;
 return;
}
/////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::LeftRotate(const T &t)
{
 StatTreeNode<T> *p = Serach(t);
 LeftRotate(p);
}
////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::RightRotate(StatTreeNode<T> *const p)
{
 if (p == NULL || p == NIL)
 {
  return;
 }
 if (p->left == NIL)
 {
  return;
 }
 StatTreeNode<T> *p2 = p->left;
 if (p2->right != NIL)
 {
  p2->right->parent = p;
 }
 p->left = p2->right;
 p2->parent = p->parent;
 if (p->parent != NIL)
 {
  if (p == p->parent->left)
  {
   p->parent->left = p2;
  }
  else
  {
   p->parent->right = p2;
  }
 }
 p->parent = p2;
 p2->right = p;
 p2->size = p->size;
 p->size = p->left->size + p->right->size + 1;
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::RightRotate(const T &t)
{
 StatTreeNode<T> *p = Serach(t);
 RightRotate(p);
}
///////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Insert(const T &t)
{
 StatTreeNode<T> *p = root;
 StatTreeNode<T> *p2 = NULL;
 while (p != NIL && p != NULL)
 {
  p2 = p;
  if (t > p->data)
  {
   p = p->right;
  }
  else
  {
   p = p->left;
  }
 }
 StatTreeNode<T> *ptem = new StatTreeNode<T>;
 ptem->data = t;
 ptem->size = 1;
 ptem->left = NIL;
 ptem->right = NIL;
 if (p == NULL)
 {
  root = ptem;
  root->color = StatTreeNode<T>::B;
  root->parent = NIL;
 }
 else
 {
  if (t > p2->data)
  {
   p2->right = ptem;
   ptem->color = StatTreeNode<T>::R;
   ptem->parent = p2;
  }
  else
  {
   p2->left = ptem;
   ptem->color = StatTreeNode<T>::R;
   ptem->parent = p2;
  }
 }
 MaintenanceSize(ptem);
 StatTreeInsertFixup(ptem);
 return ptem;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::MaintenanceSize(StatTreeNode<T> *p)
{
 p = p->parent;
 while (p != NIL)
 {
  ++p->size;
  p = p->parent;
 }
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::StatTreeInsertFixup(StatTreeNode<T> *p)
{
 while (p->parent->color == StatTreeNode<T>::R)
 {
  if (p->parent == p->parent->parent->left)
  {
   StatTreeNode<T> *y = p->parent->parent->right;
   if (y->color == StatTreeNode<T>::R)
   {
    p->color = StatTreeNode<T>::B;
    y->color = StatTreeNode<T>::B;
    p->parent->parent->color = StatTreeNode<T>::R;
    p = p->parent;
   }
   else if (p == p->parent->right)
   {
    p = p->parent;
    LeftRotate(p);
   }
   p->parent->color = StatTreeNode<T>::B;
   p->parent->parent->color = StatTreeNode<T>::R;
   RightRotate(p);
  }
  else
  {
   StatTreeNode<T> *y = p->parent->parent->left;
   if (y->color == StatTreeNode<T>::R)
   {
    p->color = StatTreeNode<T>::B;
    y->color = StatTreeNode<T>::B;
    p->parent->parent->color = StatTreeNode<T>::R;
    p = p->parent;
   }
   else if (p == p->parent->left)
   {
    p = p->parent;
    RightRotate(p);
   }
   p->parent->color = StatTreeNode<T>::B;
   p->parent->parent->color = StatTreeNode<T>::R;
   LeftRotate(p);
  }
 }
 root->color = StatTreeNode<T>::B;
 return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTreeNode<T> *StatTree<T>::Delete(const T &t)
{
 StatTreeNode<T> *p = Serach(t);
 StatTreeNode<T> *p2 = p;
 if (p->left != NIL && p->right !=NIL)
 {
  p2 = Successor(t);
  if (p2->parent == NIL)
  {
   root = p2->right;
   p2->right->parent = root;
  }
  else
  {
   if (p2 == p2->parent->left)
   {
    p2->parent->left = p2->right;
   }
   else
   {
    p2->parent->right = p2->right;
   }
  }
  p2->right->parent = p2->parent;
  swap(p->data,p2->data); 
  p = p2;  
  p2 = p2->right;
 }
 else
 {
  if (p->left != NIL && p->right == NIL)
  {
   if (p->parent == NIL)
   {
    root = p->left;
    p->left->parent = NIL;
   } 
   else if (p == p->parent->left)
   {
    p->parent->left = p->left;
    p->left->parent = p->parent;
   }
   else
   {
    p->parent->right = p->left;
    p->left->parent = p->right;
   }
   p2 = p->left;
  }
  else if (p->left == NIL && p->right != NIL)
  {
   if (p->parent == NIL)
   {
    root = p->right;
    p->right->parent = NIL;
   }
   else if (p == p->parent->left)
   {
    p->parent->left = p->right;
    p->right->parent = p->parent;
   }
   else
   {
    p->parent->right = p->right;
    p->right->parent = p->parent;
   }
   p2 = p->right;
  }
  else
  {
   if (p->parent == NIL)
   {
    root = NULL;
   }
   else if (p == p->parent->left)
   {
    p->parent->left = NIL;
   }
   else
   {
    p->parent->right = NIL;
   }
   p2 = p->right;
  }
 }
 if (p->color == StatTreeNode<T>::B)
 {
  StatTreeDeleteFixup(p2);
 }
 return p;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::StatTreeDeleteFixup(StatTreeNode<T> *x)
{
 if (root == NULL)
 {
  return;
 }
 while (x != root && x->color == StatTreeNode<T>::B)
 {
  if (x == x->parent->left)
  {
   StatTreeNode<T> *w = x->parent->right;
   if (w->color == StatTreeNode<T>::R)
   {
    w->color = StatTreeNode<T>::B;
    LeftRotate(x->parent);
    w = x->parent->right;
   }
   if (w->left->color == StatTreeNode<T>::B && w->right->color == StatTreeNode<T>::B)
   {
    w->color = StatTreeNode<T>::R;
    x = x->parent;
   }
   else if (w->right->color == StatTreeNode<T>::B)
   {
    w->left->color = StatTreeNode<T>::B;
    w->color = StatTreeNode<T>::R;
    RightRotate(w);
    w = x->right->right;
    w->color = x->parent->color;
    x->parent->color = StatTreeNode<T>::B;
    w->right->color = StatTreeNode<T>::B;
    LeftRotate(x->parent);
    x = root;
   }
  }
  else
  {
   StatTreeNode<T> *w = x->parent->left;
   if (w->color == StatTreeNode<T>::R)
   {
    w->color = StatTreeNode<T>::B;
    RightRotate(x->parent);
    w = x->parent->left;
   }
   if (w->right->color == StatTreeNode<T>::B && w->left->color == StatTreeNode<T>::B)
   {
    w->color = StatTreeNode<T>::R;
    x = x->parent;
   }
   else if (w->left->color == StatTreeNode<T>::B)
   {
    w->right->color = StatTreeNode<T>::B;
    w->color = StatTreeNode<T>::R;
    LeftRotate(w);
    w = x->parent->left;
    w->color = x->parent->color;
    x->parent->color = StatTreeNode<T>::B;
    w->left->color = StatTreeNode<T>::B;
    RightRotate(x->parent);
    x = root;
   }
  }
  x->color = StatTreeNode<T>::B;
 }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Clear()
{
 if (root != NULL)
 {
  Destory(root);
  root = NULL;
 }
 return;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
void StatTree<T>::Destory(StatTreeNode<T> *p)
{
 while (p != NIL)
 {
  Destory(p->left);
  Destory(p->right);
  delete p;
  p = NIL;
 }
 return;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T>
StatTree<T>::~StatTree()
{
 Clear();
 if (NIL != NULL)
 {
  delete NIL;
 }
}
 

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广泛的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值