判断完全二叉树
bool isCBT(TreeNode* root) {
if (!root)
return true;
queue<TreeNode*> q;
q.push(root);
bool leaf = false; //是否必须为叶子节点
while (!q.empty())
{
TreeNode* node = q.front();
q.pop();
if (!node->left && node->right) //仅有右子节点,无左子节点
return false;
if (leaf) //前面出现过无右子节点的 (只有左 或 左右都没有的) 后续所有节点必须为叶子节点
{
if (node->left || node->right) //非叶子节点
return false;
}
if (node->left)
q.push(node->left);
if (node->right)
q.push(node->right);
else //右为空 则后续节点必须为叶子节点
leaf = true;
}
return true;
}
判断搜索二叉树
递归实现
bool judgesearch(TreeNode* root,int low,int high)
{
if(root==NULL) return true;
if(root->val<=low||root->val>=high) return false;
return judgesearch(root->left,low,root->val)&&judgesearch(root->right,root->val,high);
}
栈实现,借助中序遍历,保存上一位状态
class Solution {
public:
bool isValidBST(TreeNode* root) {
stack<TreeNode*> stack;
long long inorder = (long long)INT_MIN - 1;
while (!stack.empty() || root != nullptr) {
while (root != nullptr) {
stack.push(root);
root = root -> left;
}
root = stack.top();
stack.pop();
// 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
if (root -> val <= inorder) return false;
inorder = root -> val;
root = root -> right;
}
return true;
}
};
二叉搜索第k小的节点
搜索k次
TreeNode* KthNode(TreeNode* root, int k)
{
if(k<=0) return NULL;
stack<TreeNode*> stack1;
while(k>0&&(!stack1.empty()||root!=NULL))
{
while(root!=NULL)
{
stack1.push(root);
root=root->left;
}
root=stack1.top();
stack1.pop();
k--;
if(k==0) break;
root=root->right;
}
return root;
}
110 判断平衡二叉树(高度平衡,相差1
104 二叉树最大深度(从根到叶子节点最长的路径
543 二叉树的直径
二叉树的最小深度(到叶子节点
int mindep(TreeNode* root)
{
if (root == NULL) return 0;
int left = mindep(root->left);
int right = mindep(root->right);
if (left == 0 || right == 0) return left + right + 1;
return min(left, right) + 1;
}
二叉树求k层节点个数
int getknum(TreeNode* root,int k)
{
if (root == NULL || k == 0) return 0;
queue<TreeNode*> q;
q.push(root);
if (k == 1) return 1;
int ans = 0;
while (k > 1 && !q.empty())
{
k--;
int curt = q.size();
while (curt)
{
TreeNode* cur = q.front();
q.pop();
curt--;
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
}
ans = q.size();
}
if (k != 1) return 0;
return ans;
}
二叉搜索树前序得到中序
void getMidTravel(vector<int> &a, int begin, int end, vector<int> &result, int offset) {
if (begin > end) return;
if (begin == end) {
result[begin + offset] = a[begin];
return;
}
int i = begin + 1;
for (; i < a.size() && a[i] < a[begin]; i++);
result[i - 1 + offset] = a[begin];
getMidTravel(a, begin + 1, i - 1, result, offset - 1);
getMidTravel(a, i, end, result, offset);
}
vector<int> getMidTravels(vector<int> a) {
vector<int> result(a.size());
getMidTravel(a, 0, a.size() - 1, result, 0);
return result;
}
235 二叉搜索树公共祖先
236 二叉树公共祖先
543 二叉树最长路径
求每个节点左子树的高度和右子树高度,相加加1就是路径长
二叉树搜索树转双向链表
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode* pLastNode = NULL;//指向双向链表的尾结点
ConvertNode(pRootOfTree, &pLastNode);
//找到头结点
TreeNode* pHead = pLastNode;
while (pHead != NULL&&pHead->left != NULL)
pHead = pHead->left;
return pHead;
}
//中序遍历过程
void ConvertNode(TreeNode* pNode, TreeNode** pLastNode)
{
if (pNode == NULL)
return;
TreeNode* pCur = pNode;
if (pCur->left != NULL)
ConvertNode(pCur->left, pLastNode);
pCur->left = *pLastNode;
if (*pLastNode != NULL)
(*pLastNode)->right = pCur;
*pLastNode = pCur;
if (pCur->right != NULL)
ConvertNode(pCur->right, pLastNode);
}
};
验证二叉搜索树后续遍历
bool verifyPostorder(vector<int>& postorder) {
return helper(postorder,0,postorder.size()-1);
}
bool helper(vector<int>& post,int lo, int hi){
if(lo >= hi) return true; //单节点或空节点返回true
int root = post[hi]; //后序遍历序列最后的值为根节点的值
int l = lo;
while(l<hi && post[l]<root)
l++; //遍历左子树(值小于根),左子树序列post[lo, l);
int r = l;
while(r<hi && post[r]>root)
r++; //遍历右子树(值大于根),右子树序列post[l, r);
if(r != hi) return false;//若未将post[l, hi)遍历完,则非后序遍历序列 返回false
return helper(post, lo, l-1) && helper(post, l, hi-1); //递归检查左右子树
}