[数据结构]二叉树OJ(leetcode)

目录

二叉树OJ(leetcode)训练习题::

                                                1.单值二叉树

​                                                2.检查两棵树是否相同 

                                                3.二叉树的前序遍历

                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        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;
}

 

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值