目录
4.二叉树的中序遍历
5.二叉树的后序遍历
6.二叉树的最大深度
7.平衡二叉树
8.另一棵树的子树
9.二叉树的构建及遍历
10.二叉树的销毁
11.判断二叉树是否是完全二叉树
二叉树OJ(leetcode)训练习题::
1.单值二叉树
struct TreeNode
{
int val;
struct TreeNode* left;
struct TreeNode* right;
};
bool isUnivalTree(struct TreeNode* root)
{
if (root == NULL)
return true;
if (root->left && root->val != root->left->val)
return false;
if (root->right && root->val != root->right->val)
return false;
//走到此位置说明当前的父亲和孩子是相等的
return isUnivalTree(root->left) && isUnivalTree(root->right);
}
单值二叉树递归图解:
单值二叉树递归展开图:
2.检查两棵树是否相同
//相同的树
//思路:根比较 子树比较
struct TreeNode
{
int val;
struct TreeNode* left;
struct TreeNode* right;
};
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if (p == NULL && q == NULL)
return true;
//其中一个为空 另一个不为空
if (p == NULL || q == NULL)
return false;
//都不为空
if (p->val != q->val)
return false;
//走到此位置说明p,q均不为空,且根的值是相等的
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
相同的树递归图解:
相同的树递归展开图:
3.二叉树的前序遍历
//二叉树的前序遍历
//要求:既要返回数组的首地址 又要返回数组的长度
struct TreeNode
{
int val;
struct TreeNode* left;
struct TreeNode* right;
};
int TreeSize(struct TreeNode* root)
{
if (root == NULL)
return 0;
return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void preorder(struct TreeNode* root, int* a, int* pi)
{
if (root == NULL)
return;
a[*pi] = root->val;
(*pi)++;
preorder(root->left, a, pi);
preorder(root->right, a, pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
int n = TreeSize(root);
int* a = (int*)malloc(sizeof(int) * n);
int i = 0;
preorder(root, a, &i);
*returnSize = n;
return a;
}
二叉树的前序遍历递归展开图:
4.二叉树的中序遍历
int TreeSize(struct TreeNode* root)
{
if (root == NULL)
return 0;
return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void inorder(struct TreeNode* root, int* a, int* pi)
{
if (root == NULL)
return;
inorder(root->left, a, pi);
a[*pi] = root->val;
(*pi)++;
inorder(root->right, a, pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
int n = TreeSize(root);
int* a = (int*)malloc(sizeof(int) * n);
int i = 0;
inorder(root, a, &i);
*returnSize = n;
return a;
}
5.二叉树的后序遍历
int TreeSize(struct TreeNode* root)
{
if (root == NULL)
return 0;
return TreeSize(root->left) + TreeSize(root->right) + 1;
}
void postorder(struct TreeNode* root, int* a, int* pi)
{
if (root == NULL)
return;
postorder(root->left, a, pi);
postorder(root->right, a, pi);
a[*pi] = root->val;
(*pi)++;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
int n = TreeSize(root);
int* a = (int*)malloc(sizeof(int) * n);
int i = 0;
postorder(root, a, &i);
*returnSize = n;
return a;
}
6.二叉树的最大深度
int maxDepth(struct TreeNode* root)
{
if(root == NULL)
{
return 0;
}
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
7.平衡二叉树
//代码1
int maxDepth(struct TreeNode* root)
{
if (root == NULL)
{
return 0;
}
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
}
bool isBalanced(struct TreeNode* root)
{
if (root == NULL)
return true;
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return abs(leftDepth - rightDepth) <= 1
&& isBalanced(root->left)
&& isBalanced(root->right);
}
//代码2:
bool isBalanced(struct TreeNode* root)
{
if (root == NULL)
return true;
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
int high = abs(leftDepth - rightDepth);
if (high >= 2)
return false;
return isBalanced(root->left) && isBalanced(root->right);
}
平衡二叉树递归展开图:
8.另一棵树的子树
//另一棵树的子树
struct TreeNode
{
int val;
struct TreeNode* left;
struct TreeNode* right;
};
bool isSameTree(struct TreeNode* p, struct TreeNode* q)
{
if (p == NULL && q == NULL)
return true;
//其中一个为空 另一个不为空
if (p == NULL || q == NULL)
return false;
//都不为空
if (p->val != q->val)
return false;
//走到此位置说明p,q均不为空,且根的值是相等的
return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot)
{
if (root == NULL)
return false;
if (isSameTree(root, subRoot))
return true;
return isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
}
另一棵树的子树递归展开图:
9.二叉树的构建及遍历
//二叉树遍历
//通过前序遍历的数组构建二叉树
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
BTNode* BinaryTreeCreate(BTDataType* a, int* pi)
{
if (a[*pi] == '#')
{
(*pi)++;
return NULL;
}
BTNode* root = (BTNode*)malloc(sizeof(BTNode));
if (root == NULL)
{
perror("malloc fail");
return NULL;
}
root->data = a[*pi];
(*pi)++;
root->left = BinaryTreeCreate(a, pi);
root->right = BinaryTreeCreate(a, pi);
return root;
}
void InOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
InOrder(root->left);
printf("%c ", root->data);
InOrder(root->right);
}
int main()
{
char str[100];
scanf("%s", str);
int i = 0;
BTNode* root = BinaryTreeCreate(str, &i);
InOrder(root);
return 0;
}
二叉树的构建及遍历递归展开图:
10.二叉树的销毁
//二叉树销毁
//外面调用该函数的人置空
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
void BinaryTreeDestory(BTNode* root)
{
if (root == NULL)
{
return;
}
BinaryTreeDestory(root->left);
BinaryTreeDestory(root->right);
free(root);
}
二叉树的销毁递归图解:
二叉树销毁递归展开图:
11.判断二叉树是否是完全二叉树
//判断二叉树是否是完全二叉树
typedef int QDataType;
typedef struct QueueNode
{
struct QueueNode* next;
QDataType data;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL && pq->tail == NULL;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* del = cur;
cur = cur->next;
free(del);
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
else
{
newnode->data = x;
newnode->next = NULL;
}
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL)
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* del = pq->head;
pq->head = pq->head->next;
free(del);
del = NULL;
}
pq->size--;
}
//取队列头部数据
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
//取队列尾部数据
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
int QueueSize(Queue* pq)
{
assert(pq);
return pq->size;
}
int BinaryTreeComplete(BTNode* root)
{
Queue q;
QueueInit(&q);
if (root)
QueuePush(&q, root);
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front == NULL)
{
break;
}
QueuePush(&q, front->left);
QueuePush(&q, front->right);
}
//遇到空以后 后面全是空 则是完全二叉树
//遇到空以后 后面存在非空 则不是完全二叉树
while (!QueueEmpty(&q))
{
BTNode* front = QueueFront(&q);
QueuePop(&q);
if (front != NULL)
{
QueueDestory(&q);
return false;
}
}
QueueDestory(&q);
return true;
}