目录
二叉树概念
二叉树的遍历方式
DFS(前序 中序 后序遍历)
144. 二叉树的前序遍历
递归解法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#define MAX_NUM 100
void PreTra(int *arr, int *returnSize, struct TreeNode *node)
{
if (node == NULL) {
return;
}
arr[(*returnSize)++] = node->val;
PreTra(arr, returnSize, node->left);
PreTra(arr, returnSize, node->right);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
*returnSize = 0;
int *res = malloc(sizeof(int) * MAX_NUM);
PreTra(res, returnSize, root);
return res;
}
迭代解法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#define MAX_NUM 100
int* preorderTraversal(struct TreeNode* root, int* returnSize)
{
int top = 0;
struct TreeNode* stack[MAX_NUM];
stack[top++] = root;
struct TreeNode* node;
int *res = malloc(sizeof(int) * MAX_NUM);
*returnSize = 0;
while (top != 0) {
node = stack[--top];
if (node == NULL) {
break;
}
res[(*returnSize)++] = node->val;
if (node->right != NULL) {
stack[top++] = node->right;
}
if (node->left != NULL) {
stack[top++] = node->left;
}
}
return res;
}
94. 二叉树的中序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#define MAX_NUM 100
void InorderTra(int *arr, int *returnSize, struct TreeNode *node)
{
if (node == NULL) {
return;
}
InorderTra(arr, returnSize, node->left);
arr[(*returnSize)++] = node->val;
InorderTra(arr, returnSize, node->right);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize)
{
*returnSize = 0;
int *res = malloc(sizeof(int) * MAX_NUM);
InorderTra(res, returnSize, root);
return res;
}
145. 二叉树的后序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
#define MAX_NUM 100
void PostTra(int *arr, int *returnSize, struct TreeNode *node)
{
if (node == NULL) {
return;
}
PostTra(arr, returnSize, node->left);
PostTra(arr, returnSize, node->right);
arr[(*returnSize)++] = node->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize)
{
*returnSize = 0;
int *res = malloc(sizeof(int) * MAX_NUM);
PostTra(res, returnSize, root);
return res;
}
层序遍历--队列的作用
102. 二叉树的层序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
#define MAX_LEN 2000
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes)
{
*returnSize = 0;
if (root == NULL) {
return NULL;
}
int **res = (int **)malloc(sizeof(int *) * MAX_LEN);
*returnColumnSizes = (int *)malloc(sizeof(int) * MAX_LEN);
struct TreeNode *node = root;
struct TreeNode *list[MAX_LEN];
int head, tail;
head = 0, tail = 0;
list[tail++] = node; // 第一次入队
int lastTail, index;
while (head != tail) {
lastTail = tail;
// 申请内存
res[(*returnSize)] = malloc(sizeof(int) * (tail - head));
(*returnColumnSizes)[(*returnSize)] = tail - head;
index = 0;
while (head < lastTail) {
// 出队
node = list[head++];
res[(*returnSize)][index++] = node->val;
if (node->left != NULL) {
list[tail++] = node->left;
}
if (node->right != NULL) {
list[tail++] = node->right;
}
}
(*returnSize)++;
}
return res;
}
107. 二叉树的层序遍历 II
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
#define MAX_LEN 2001
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes)
{
*returnSize = 0;
if (root == NULL) {
return NULL;
}
struct TreeNode *node = root;
int **res = (int **)malloc(sizeof(int *) * MAX_LEN);
*returnColumnSizes = (int *)malloc(sizeof(int) * MAX_LEN);
int head, tail;
head = 0, tail = 0;
struct TreeNode *list[MAX_LEN];
list[tail++] = node; // 第一次入栈
int lastTail, col;
while (head != tail) {
lastTail = tail;
col = 0;
// 申请内存
res[(*returnSize)] = (int *)malloc(sizeof(int) * (tail - head)); // 开大一点
(*returnColumnSizes)[(*returnSize)] = tail - head;
while (head != lastTail) {
node = list[head++];
res[(*returnSize)][col++] = node->val;
if (node->left != NULL) {
list[tail++] = node->left;
}
if (node->right != NULL) {
list[tail++] = node->right;
}
}
(*returnSize)++;
}
// reverse
int left, right, tmpNum;
left = 0, right = (*returnSize) - 1;
// printf("left %d, right %d\n", left, right);
// int *tmp = malloc(sizeof(int) * MAX_LEN);
while (left < right) {
// memcpy(tmp, res[left], sizeof(int) * (*returnColumnSizes)[left]);
// memcpy(res[left], res[right], sizeof(int) * (*returnColumnSizes)[right]);
// memcpy(res[right], tmp, sizeof(int) * (*returnColumnSizes)[left]);
int *tmp = res[left];
res[left] = res[right];
res[right] = tmp;
tmpNum = (*returnColumnSizes)[left];
(*returnColumnSizes)[left] = (*returnColumnSizes)[right];
(*returnColumnSizes)[right] = tmpNum;
left++;
right--;
}
return res;
}
429. N 叉树的层序遍历
/**
* Definition for a Node.
* struct Node {
* int val;
* int numChildren;
* struct Node** children;
* };
*/
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
#define MAX_LEN 1001
#define MAX_HIGH 10001
int** levelOrder(struct Node* root, int* returnSize, int** returnColumnSizes)
{
int **res = (int **)malloc(sizeof(int *) * MAX_LEN);
*returnColumnSizes = (int *)malloc(sizeof(int) * MAX_LEN);
*returnSize = 0;
if (root == NULL) {
return res;
}
struct Node* node = root;
struct Node *list[MAX_HIGH];
int head, tail;
head = 0, tail = 0;
list[tail++] = node;
int lastTail, col;
while (head != tail) {
col = 0;
lastTail = tail;
// 申请内存
res[(*returnSize)] = malloc(sizeof(int) * (tail - head));
(*returnColumnSizes)[(*returnSize)] = (tail - head);
while (head != lastTail) {
node = list[head++]; // 出队
res[(*returnSize)][col++] = node->val;
// 入队
for (int j = 0; j < node->numChildren; j++) {
list[tail++] = node->children[j];
}
}
(*returnSize)++;
}
return res;
}
二叉搜索树
98. 验证二叉搜索树
graph graphname {
a -- b -- c;
b -- d;
}
-
思路1:利用中序遍历,将二叉树转换为数组,然后判断数组是否有序
-
思路2:直接在递归过程中,有两个指针模拟左(pre)->中(cur)->右,左->中(pre)->右(cur)
- 陷阱:不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了,要比较的是左子树所有节点小于中间节点,右子树所有节点大于中间节点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
bool isOk(struct TreeNode *cur, struct TreeNode **pre)
{
if (cur == NULL) return true; // 先沉底
bool left = isOk(cur->left, pre);
if (*pre != NULL && (*pre)->val >= cur->val) {
return false;
}
// if (*pre != NULL) printf("cur=%d, pre=%d\n", cur->val, (*pre)->val);
*pre = cur;
bool right = isOk(cur->right, pre);
return left && right;
}
bool isValidBST(struct TreeNode* root)
{
struct TreeNode *pre = NULL;
return isOk(root, &pre);
}
- 思路3:迭代法,用栈模拟递归压栈和弹栈的过程
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
#define MAX_NUM 10000
bool isValidBST(struct TreeNode* root)
{
int top = 0;
struct TreeNode *stack[MAX_NUM];
struct TreeNode *cur = root;
struct TreeNode *pre = NULL;
// 用栈模拟 递归压栈和弹栈的过程
while (cur != NULL || top != 0) {
if (cur != NULL) {
stack[top++] = cur;
cur = cur->left; // 左
} else {
cur = stack[--top];
if (pre != NULL && pre->val >= cur->val) return false;
pre = cur;
cur = cur->right;
}
}
return true;
}
700. 二叉搜索树中的搜索
- 递归
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* searchBST(struct TreeNode* root, int val)
{
if (root == NULL) return NULL;
if (root->val == val) {
return root;
} else if (root->val > val) {
return searchBST(root->left, val);
} else {
return searchBST(root->right, val);
}
return NULL;
}
- 迭代法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* searchBST(struct TreeNode* root, int val)
{
while (root != NULL) {
if (root->val == val) {
return root;
} else if (root->val > val) {
root = root->left;
} else {
root = root->right;
}
}
return NULL;
}
501. 二叉搜索树中的众数
- 中序遍历1次搞定,不适用额外的空间:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int g_preVal, g_count, g_maxCount;
int g_resSize;
int *g_res;
void Update(int curVal)
{
if (curVal == g_preVal) {
g_count++;
} else {
g_preVal = curVal;
g_count = 1;
}
if (g_count == g_maxCount) {
g_res[g_resSize++] = curVal;
}
if (g_count > g_maxCount) {
g_maxCount = g_count;
g_resSize = 0;
g_res[g_resSize++] = curVal;
}
}
/* 中序遍历 */
void MidTravle(struct TreeNode *node)
{
if (node == NULL) return;
MidTravle(node->left);
Update(node->val);
MidTravle(node->right);
}
int* findMode(struct TreeNode* root, int* returnSize)
{
g_count = 0, g_maxCount = 0, g_resSize = 0;
g_preVal = root->val;
g_res = malloc(sizeof(int) * 10001);
MidTravle(root);
*returnSize = g_resSize;
return g_res;
}
- 使用hash表记录出现次数,使用了额外空间,并且还需要排序
struct HashTable {
int num;
int count;
UT_hash_handle hh;
};
struct HashTable *g_hash;
int g_count = 0;
struct HashTable *FindeNode(int num)
{
struct HashTable *tmp = NULL;
HASH_FIND_INT(g_hash, &num, tmp);
return tmp;
}
void AddNode(int num)
{
struct HashTable *tmp = FindeNode(num);
if (tmp == NULL) {
g_count++;
tmp = malloc(sizeof(struct HashTable));
tmp->num = num;
tmp->count = 1;
HASH_ADD_INT(g_hash, num, tmp);
} else {
tmp->count++;
}
}
void Func(struct TreeNode *node)
{
if (node == NULL) return;
AddNode(node->val);
Func(node->left);
Func(node->right);
}
int HashSort(struct HashTable *a, struct HashTable *b)
{
return b->count - a->count;
}
int* findMode(struct TreeNode* root, int* returnSize)
{
// 1、遍历整棵树
// 2、记录每个数字出现的次数
// 3、返回出现次数最高的数
g_hash = NULL;
Func(root);
HASH_SORT(g_hash, HashSort);
int n = g_hash->count;
int *res = malloc(sizeof(int) * g_count);
*returnSize = 0;
struct HashTable *cur, *tmp;
HASH_ITER(hh, g_hash, cur, tmp) {
if (cur->count == n) {
res[(*returnSize)++] = cur->num;
}
HASH_DEL(g_hash, cur);
free(cur);
}
return res;
}
108. 将有序数组转换为二叉搜索树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode *Func(int *arr, int len)
{
if (len == 0) return;
int mid = len / 2;
struct TreeNode *node = malloc(sizeof(struct TreeNode));
node->val = arr[mid];
node->left = Func(arr, mid);
node->right = Func(arr + mid + 1, len - mid - 1);
return node;
}
struct TreeNode* sortedArrayToBST(int* nums, int numsSize)
{
if (numsSize == 0) return NULL;
struct TreeNode *root = Func(nums, numsSize);
return root;
}
二叉树剪枝
450.删除二叉搜索树中的节点
- 涉及到树结构的调整,较为复杂
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* deleteNode(struct TreeNode* root, int key)
{
if (root == NULL) return NULL;
if (root->val == key) {
if (root->left == NULL && root->right == NULL) {
free(root);
return NULL;
}
if (root->left != NULL && root->right == NULL) {
struct TreeNode *node = root->left;
free(root);
return node;
}
if (root->left == NULL && root->right != NULL) {
struct TreeNode *node = root->right;
free(root);
return node;
}
// 左右孩子都非空
struct TreeNode *left = root->left; // 左
struct TreeNode *right = root->right; // 左
struct TreeNode *node = right; // 左
free(root);
while (right->left != NULL) {
right = right->left;
}
// 挂上
right->left = left;
return node;
}
if (root->val > key) {
root->left = deleteNode(root->left, key);
}
if (root->val < key) {
root->right = deleteNode(root->right, key);
}
return root;
}
回溯思想
236. 二叉树的最近公共祖先
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/*
* 1.前序遍历
* 2.左子树和右子树每颗树都完整的遍历1遍
* 3.回溯,利用左子树和右子树的返回值,来判断最近公共祖先
*/
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q)
{
if (root == p || root == q || root == NULL) return root;
struct TreeNode *left = lowestCommonAncestor(root->left, p, q);
struct TreeNode *right = lowestCommonAncestor(root->right, p, q);
if (left != NULL && right != NULL) return root;
if (left == NULL && right != NULL) return right;
return left;
}
235. 二叉搜索树的最近公共祖先
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q)
{
if (root == NULL || root == q || root == p) return root;
int val = root->val;
if (p->val < val && q->val < val) {
return lowestCommonAncestor(root->left, p, q);
} else if (p->val > val && q->val >val) {
return lowestCommonAncestor(root->right, p, q);
} else {
return root;
}
}
二叉树中的插入操作
701.二叉搜索树中的插入操作
- 递归解法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* insertIntoBST(struct TreeNode* root, int val)
{
if (root == NULL) {
struct TreeNode *node = malloc(sizeof(struct TreeNode));
node->val = val;
node->left = NULL;
node->right = NULL;
root = node;
return root;
}
if (root->val > val) {
root->left = insertIntoBST(root->left, val);
}
if (root->val < val) {
root->right = insertIntoBST(root->right, val);
}
return root;
}
- 迭代解法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* insertIntoBST(struct TreeNode* root, int val)
{
struct TreeNode *node = root;
struct TreeNode *add = malloc(sizeof(struct TreeNode));
add->val = val;
add->left = NULL;
add->right = NULL;
if (node == NULL) return add;
while (node != NULL) {
if (node->val > val && node->left == NULL) {
node->left = add;
break;
}
if (node->val < val && node->right == NULL) {
node->right = add;
break;
}
if (node->left != NULL && val < node->val) {
node = node->left;
}
if (node->right != NULL && val > node->val) {
node = node->right;
}
}
return root;
}
构建二叉树
105. 从前序与中序遍历序列构造二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize)
{
if (preorderSize == 0) return NULL;
int leftSize, rightSize;
struct TreeNode *node = malloc(sizeof(struct TreeNode));
node->val = preorder[0];
for (int i = 0; i < inorderSize; i++) {
if (node->val == inorder[i]) {
leftSize = i;
break;
}
}
rightSize = inorderSize - leftSize - 1;
node->left = buildTree(preorder + 1, leftSize, inorder, leftSize);
node->right = buildTree(preorder + 1 + leftSize, rightSize, inorder + leftSize + 1, rightSize);
return node;
}
106. 从中序与后序遍历序列构造二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int Search(int* inorder, int inorderSize, int target)
{
for (int i = 0; i < inorderSize; i++) {
if (target == inorder[i]) {
return i;
}
}
return -1;
}
struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize)
{
if (inorderSize == 0) {
return NULL;
}
struct TreeNode *node = malloc(sizeof(struct TreeNode));
node->val = postorder[postorderSize - 1];
int index = Search(inorder, inorderSize, node->val);
int rightSize = inorderSize - index - 1;
int leftSize = index;
node->left = buildTree(inorder, leftSize, postorder, leftSize);
node->right = buildTree(inorder + index + 1, rightSize, postorder + leftSize, rightSize);
return node;
}
108.将有序数组转换为二叉搜索树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode *Func(int *arr, int len)
{
if (len == 0) return;
int mid = len / 2;
struct TreeNode *node = malloc(sizeof(struct TreeNode));
node->val = arr[mid];
node->left = Func(arr, mid);
node->right = Func(arr + mid + 1, len - mid - 1);
return node;
}
struct TreeNode* sortedArrayToBST(int* nums, int numsSize)
{
if (numsSize == 0) return NULL;
struct TreeNode *root = Func(nums, numsSize);
return root;
}
完全二叉树
- 待补充