二叉树 
struct  TreeNode  { int  val;TreeNode *left; TreeNode *right; TreeNode (int  x) : val (x), left (NULL ), right (NULL ) {}}; 
完全二叉树是由满二叉树而引出来的,若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数(即1~h-1层为一个满二叉树),第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
树的遍历:先根、中根、后根、层次 
先根遍历(preorder) 
递归 
void  preorder (TreeNode* root)     if (!root)         return ;     ans.push_back (root->val);     preorder (root->left);     preorder (root->right); } 
迭代 
vector<int > preorderTraversal (TreeNode* root)   {    vector<int > ans;     stack<TreeNode*> stk;     while (!stk.empty ()||root){                  while (root){             ans.push_back (root->val);             stk.push (root);             root=root->left;         }         root=stk.top ();         stk.pop ();         root=root->right;     }     return  ans; } class  Solution  {public :    vector<int > preorderTraversal (TreeNode* root)   {         stack<TreeNode *> stk;         vector<int > ans;         while (root!=nullptr ||!stk.empty ()){             while (root==nullptr &&!stk.empty ()){                 root=stk.top ();                 root=root->right;                     stk.pop ();             }             if (root){             ans.push_back (root->val);             stk.push (root);             root=root->left;}         }         return  ans;     } }; class  Solution  {public :    vector<int > preorder (Node* root)   {         vector<int > ans;         if (root==nullptr )             return  ans;         stack<Node*> stk;         stk.push (root);         while (!stk.empty ()){             Node* cur=stk.top ();             stk.pop ();             ans.push_back (cur->val);             for (int  i=cur->children.size ()-1 ;i>=0 ;i--){                 stk.push (cur->children[i]);             }         }         return  ans;     } }; 
589. N 叉树的前序遍历 - 力扣(LeetCode) 
Mirros遍历 
vector<int > preorderTraversal (TreeNode* root)   {        vector<int > ans;         TreeNode* predesessor;         while (root){             if (root->left!=nullptr ){                 predesessor=root->left;                 while (predesessor->right&&predesessor->right!=root){                     predesessor=predesessor->right;                 }                 if (predesessor->right!=root){                     predesessor->right=root;                     ans.push_back (root->val);                     root=root->left;                 }else {                      predesessor->right=nullptr ;                     root=root->right;                                     }             }else {                 ans.push_back (root->val);                 root=root->right;             }         }         return  ans;     } 
中根遍历(inorder) 
二叉树的中序遍历 - 二叉树的中序遍历 - 力扣(LeetCode) 
递归 
inorder (root){    if (!root)         return ;     inorder (root->left);     处理根结点     inorder (root->right); } 
时间复杂度:O(n),其中 n为二叉树节点的个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。
空间复杂度:O(n)。空间复杂度取决于递归的栈深度,而栈深度在二叉树为一条链的情况下会达到 O(n)的级别。
 
迭代 
沿着左侧路径下降,访问该结点,转到右侧路径
vector<int > inorderTraversal (TreeNode* root)   {        vector<int > ret;         stack<TreeNode*> stk;         while (root||!stk.empty ()){                          while (root){                 stk.push (root);                 root=root->left;             }                          root=stk.top ();             stk.pop ();             ret.push_back (root->val);             root=root->right;         }         return  ret;     } 
时间复杂度:O(n),其中 n为二叉树节点的个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。
空间复杂度:O(n)。空间复杂度取决于递归的栈深度,而栈深度在二叉树为一条链的情况下会达到 O(n)的级别。
 
Morris遍历 
mirros记录了一条返回路径,可以通过该路径访问到下一个应该访问的节点
root沿着左子树下降,并记录左子树最右侧节点返回到当前节点的路径
访问完root的左子树后,应该返回到root
如果左子树的最右侧节点已经指向了自身,说明左子树已经遍历结束,当前遍历根节点,转向右子树
 
vector<int > inorderTraversal (TreeNode* root)   {        vector<int > ret;         TreeNode *predesessor;         while (root!=nullptr ){                          if (root->left!=nullptr ){                 predesessor=root->left;                 while (predesessor->right!=nullptr &&predesessor->right!=root){                     predesessor=predesessor->right;                 } 				                                  if (predesessor->right!=root){                     predesessor->right=root;                     root=root->left;                 }                 else {                     ret.push_back (root->val);                     predesessor->right=nullptr ;                     root=root->right;                 }             }                          else {                 ret.push_back (root->val);                 root=root->right;             }         }         return  ret;     } 
后根遍历 
递归 
inorder (root){    if (!root)         return ;     inorder (root->left);     inorder (root->right);     处理根结点 } 
迭代 
class  Solution  {public :    vector<int > postorderTraversal (TreeNode* root)   {         vector<int > ans;         stack<pair<TreeNode*,int >> stk;                  while (root||!stk.empty ()){                          while (root){                 stk.push ({root,-1 });                 root=root->left;             } 			             root=stk.top ().first;             int  mark=stk.top ().second;             stk.pop ();                          if (mark==-1 ){                 stk.push ({root,0 });                 root=root->right;             }else {                 ans.push_back (root->val);                                  root=nullptr ;             }         }         return  ans;     } }; 
class  Solution  {public :    vector<int > postorderTraversal (TreeNode *root)   {         vector<int > res;         if  (root == nullptr ) {             return  res;         }         stack<TreeNode *> stk;         TreeNode *prev = nullptr ;         while  (root != nullptr  || !stk.empty ()) {             while  (root != nullptr ) {                 stk.emplace (root);                 root = root->left;             }             root = stk.top ();             stk.pop ();                          if  (root->right == nullptr  || root->right == prev) {                 res.emplace_back (root->val);                 prev = root;                 root = nullptr ;             } else  {                 stk.emplace (root);                 root = root->right;             }         }         return  res;     } }; 
Mirros遍历 
class  Solution  {public :    vector<int > postorderTraversal (TreeNode* root)   {         vector<int > ans;         TreeNode* n=root;         while (root){             if (root->left){                 TreeNode* predecessor=root->left;                 while (predecessor->right&&predecessor->right!=root){                     predecessor=predecessor->right;                 }                 if (predecessor->right==nullptr ){                     predecessor->right=root;                     root=root->left;                 }else {                     predecessor->right=nullptr ;                     addPath (root->left,ans);                     root=root->right;                 }             }else {                 root=root->right;             }         }         addPath (n,ans);         return  ans;     }     void  addPath (TreeNode* root,vector<int > &ans)          int  count=0 ;         while (root){             ans.push_back (root->val);             root=root->right;             count++;         }         reverse (ans.end ()-count,ans.end ());     } }; 
Mirros遍历比较 
LCA(latest  common ancestor) 
236. 二叉树的最近公共祖先 方法一
class  Solution  {public :    TreeNode *ans;     TreeNode* lowestCommonAncestor (TreeNode* root, TreeNode* p, TreeNode* q)   {                  if (DFS (root,p)&&DFS (root,q)){             ans=root;         }else {             return  NULL ;         } 		         if (lowestCommonAncestor (root->left,p,q)==NULL ){             lowestCommonAncestor (root->right,p,q);         }         return  ans;     }          bool  DFS (TreeNode* root,TreeNode *target)          if (root==NULL ){             return  false ;         }         if (root==target){             return  true ;         }         return  DFS (root->left,target)||DFS (root->right,target);     } }; 
方法二
class  Solution  {public :    TreeNode* lowestCommonAncestor (TreeNode* root, TreeNode* p, TreeNode* q)   {         if (root==NULL )             return  NULL ;         TreeNode*l=lowestCommonAncestor (root->left,p,q);         if (l!=NULL )             return  l;          TreeNode*r= lowestCommonAncestor (root->right,p,q);         if (r!=NULL )             return  r;         if (check (root,p)&&check (root,q))             return  root;         return  NULL ;     }     bool  check (TreeNode* root,TreeNode *p)          if (root==NULL )             return  false ;         if (root==p)             return  true ;         return  check (root->left,p)||check (root->right,p);     } }; 
方法三
class  Solution  {public :  TreeNode *ans;   TreeNode *lowestCommonAncestor (TreeNode *root, TreeNode *p, TreeNode *q)   {       DFS (root,p,q);       return  ans;   }   bool  DFS (TreeNode *root, TreeNode *p, TreeNode *q)      if (root==nullptr ){         return  false ;     }     bool  lson = DFS (root->left, p, q);     bool  rson = DFS (root->right, p, q);     if ((lson&&rson)||((root==p||root==q)&&(lson||rson))){         ans = root;     }     return  lson||rson||(root == p || root == q);   } }; 
class  Solution  {public :    TreeNode *lowestCommonAncestor (TreeNode *root, TreeNode *p, TreeNode *q)   {         if  (root == nullptr  || root == p || root == q)             return  root;         TreeNode *left = lowestCommonAncestor (root->left, p, q);         TreeNode *right = lowestCommonAncestor (root->right, p, q);         if  (left && right)             return  root;         return  left ? left : right;     } }; 
方法四  哈希表,记录节点父节点
class  Solution  {public :    unordered_map<int ,TreeNode*> fa;             unordered_set<TreeNode*> visited;            TreeNode* lowestCommonAncestor (TreeNode* root, TreeNode* p, TreeNode* q)   {         fa[root->val]=NULL ;         DFS (root);         while (p!=NULL ){             visited.insert (p);             p=fa[p->val];         }         while (q!=nullptr ){             if (visited.count (q))                 return  q;             q=fa[q->val];         }         return  nullptr ;     }     void  DFS (TreeNode* root)          if (root->left!=NULL ){             fa[root->left->val]=root;             DFS (root->left);         }         if (root->right!=NULL ){             fa[root->right->val]=root;             DFS (root->right);         }     } }; 
树上倍增 
1483. 树节点的第 K 个祖先 j个祖先节点,即从节点i跳2 j步到达的节点\
求节点node的第k个节点:
 
class  TreeAncestor  {public :    vector<vector<int >> dp;     TreeAncestor (int  n, vector<int >& parent) {         int  m=32 -__builtin_clz(n);                  dp.resize (n,vector <int >(m,-1 ));         for (int  i=0 ;i<n;i++){             dp[i][0 ]=parent[i];         }         for (int  i=1 ;i<m;i++){             for (int  x=0 ;x<n;x++){                 int  p=dp[x][i-1 ];                 if (p!=-1 )                     dp[x][i]=dp[p][i-1 ];             }         }     }          int  getKthAncestor (int  node, int  k)           int  m=32 -__builtin_clz(k);         for (int  i=0 ;i<m;i++){             if ((k>>i)&1 ){                 node=dp[node][i];                 if (node<0 )                     return  node;             }         }         return  node;     } }; 
最近公共祖先(LCA):通过树上倍增求 
1483. 树节点的第 K 个祖先 - 力扣(LeetCode) 
首先使a和b处于同一深度
若跳$2^i$步后,x==y(a和b的LCA和以上节点都相同),则LCA为当前节点或者下面节点,不跳 
若跳$2^i$步后,x!=y,则说明还未到达最近祖先节点,进行跳操作 
 
 
class  TreeAncestor  {  public :          vector<vector<int >> pa;     vector<int > depth;     TreeAncestor (vector<vector<int >> &edges) {         int  n = edges.size () + 1 ;         int  m = 32  - __builtin_clz(n);	         pa.resize (n, vector <int >(m, -1 ));         depth.resize (n);                  vector<vector<int >> g (n);         for  (auto  [x, y] : edges) {             g[x].push_back (y);             g[y].push_back (x);         }                  function<void <int , int >> dfs = [&](int  x, int  fa) {             pa[x][0 ] = fa;             for  (int  y : g[x]) {                 if  (y != fa) {                     depth[y] = depth[x] + 1 ;                     dfs (y, x);                 }             }         };         dfs (0 , -1 );                  for  (int  i = 1 ; i < m; i++) {             for  (int  x = 0 ; x < n; x++) {                 if  (int  p = pa[x][i - 1 ]; p != -1 )                     pa[x][i + 1 ] = pa[p][i];             }         }     }          int  getKthAncestor (int  node, int  k)           int  m = 32  - __builtin_clz(k);         for  (int  i = 0 ; i < m; i++) {             if  ((k >> i) & 1 ) {                 node = pa[node][i];                 if  (node < 0 )                     break ;             }         }         return  node;     }          int  get_kth_ancestor (int  node, int  k)           for  (; k; k &= k - 1 )             node = pa[node][__builtin_ctz(k)];         return  node;     }          int  get_lca (int  x, int  y)           if  (depth[x] > depth[y])             swap (x, y);                  y = getKthAncestor (y, depth[y] - depth[x]);         if  (y == x)             return  x;         for  (int  i = pa[x].size () - 1 ; i >= 0 ; i--) {             int  px = pa[x][i], py = pa[y][i];             if  (px != py) {                 x = px;                 y = py;             }         }         return  pa[x][0 ];     } }; 
OptimalBST(最优搜索二叉树) 
二叉查找树(Binary Search Tree,BST) 是一种特殊的二叉树:对于每个父节点,其左子节点的值小于等于父节点的值,其右子节点的值大于等于父节点的值。可以在$O(nlogn)$的时间内查找一个值是否存在。
 
class  BST  {    struct  TreeNode  {         int  val;         TreeNode *left, *right;     };     class  Solution  {       public :         TreeNode *deleteNode (TreeNode *root, int  key)   {             if  (root == nullptr ) {                 return  root;             }             if  (root->val < key) {                 root->right = deleteNode (root->right, key);             } else  if  (root->val > key) {                 root->left = deleteNode (root->left, key);             } else  {                                  if  (root->right == nullptr ) {                     return  root->left;                 }                                  if  (root->left == nullptr ) {                     return  root->right;                 }                                  TreeNode *successor = root->left;                 while  (successor->right) {                     successor = successor->right;                 }                                                                                                                                        root->val = successor->val;                 root->left = deleteNode (root->left, root->val);             }             return  root;         }     }; }; 
删除二叉搜索树中的节点 - 删除二叉搜索树中的节点 - 力扣(LeetCode)