hello-algo/codes/c/chapter_tree/array_binary_tree.c
gonglja 9900e0c668
Add array_binary_tree.c and update push_back and pop_back in vector.h (#664)
* fix(codes/cpp): Memory leak fix: the space was not freed when pop removed the element.

* fix(codes/cpp): Fix access error when printArray(arr, 0)

* Update PrintUtil.hpp

* fix(codes/c): Fix some errors of cmake build

* feat(codes/c): Add hashing_search.c

* styles(codes/c): Modify function description

* styles(codes/c): Modify binary_search.c code style

* fix(codes/c): Fix the problem in binary_tree_bfs.c and the problem that the memory is not released.

* feat: Add preorder_traversal_i_compact.c

* feat(codes/c): Add head_sort.c

* feat(codes/c): Add bucket_sort.c

* feat(codes/c): Add binary_search_edge.c

* fix(codes/c): Add programs that are not managed by cmake (c code)

* feat(codes/c): Add selection_sort.c

* style(codes/c): Change swap in selection_sort.c to `selectionSort`

* styles(codes/c): Change style.

* fix(codes/c): Fix some formatting errors and temporarily remove backtracking chapters

* fix(codes/c): Fix space_complexity.c build error.

* feat(codes/c): Add array_binary_tree.c

* feat(code/c): Update push_back and pop_back in vector.h

* styles(codes/c): Adjust  format.

---------

Co-authored-by: Yudong Jin <krahets@163.com>
2023-08-03 14:48:10 +08:00

159 lines
4.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* File: array_binary_tree.c
* Created Time: 2023-07-29
* Author: Gonglja (glj0@outlook.com)
*/
#include "../utils/common.h"
struct arrayBinaryTree {
vector *tree;
};
typedef struct arrayBinaryTree arrayBinaryTree;
arrayBinaryTree *newArrayBinaryTree(vector *arr) {
arrayBinaryTree *newABT = malloc(sizeof(arrayBinaryTree));
newABT->tree = arr;
return newABT;
}
/* 节点数量 */
int size(arrayBinaryTree *abt) {
return abt->tree->size;
}
/* 获取索引为 i 节点的值 */
int val(arrayBinaryTree *abt, int i) {
// 若索引越界,则返回 INT_MAX ,代表空位
if (i < 0 || i >= size(abt))
return INT_MAX;
return *(int *)abt->tree->data[i];
}
/* 获取索引为 i 节点的左子节点的索引 */
int left(int i) {
return 2 * i + 1;
}
/* 获取索引为 i 节点的右子节点的索引 */
int right(int i) {
return 2 * i + 2;
}
/* 获取索引为 i 节点的父节点的索引 */
int parent(int i) {
return (i - 1) / 2;
}
/* 深度优先遍历 */
void dfs(arrayBinaryTree *abt, int i, const char *order, vector *res) {
// 若为空位,则返回
if (val(abt, i) == INT_MAX)
return;
// 前序遍历
if (strcmp(order, "pre") == 0) {
int tmp = val(abt, i);
vectorPushback(res, &tmp, sizeof(tmp));
}
dfs(abt, left(i), order, res);
// 中序遍历
if (strcmp(order, "in") == 0) {
int tmp = val(abt, i);
vectorPushback(res, &tmp, sizeof(tmp));
}
dfs(abt, right(i), order, res);
// 后序遍历
if (strcmp(order, "post") == 0) {
int tmp = val(abt, i);
vectorPushback(res, &tmp, sizeof(tmp));
}
}
/* 层序遍历 */
vector *levelOrder(arrayBinaryTree *abt) {
vector *res = newVector();
// 直接遍历数组
for (int i = 0; i < size(abt); i++) {
if (val(abt, i) != INT_MAX) {
int tmp = val(abt, i);
vectorPushback(res, &tmp, sizeof(int));
}
}
return res;
}
/* 前序遍历 */
vector *preOrder(arrayBinaryTree *abt) {
vector *res = newVector();
dfs(abt, 0, "pre", res);
return res;
}
/* 中序遍历 */
vector *inOrder(arrayBinaryTree *abt) {
vector *res = newVector();
dfs(abt, 0, "in", res);
return res;
}
/* 后序遍历 */
vector *postOrder(arrayBinaryTree *abt) {
vector *res = newVector();
dfs(abt, 0, "post", res);
return res;
}
/* 打印向量中的元素 */
void printFunc(vector *v, void *p) {
int *val = p;
printf("%d", *val);
}
/* Driver Code */
int main() {
// 初始化二叉树
// 使用 INT_MAX 代表空位 nullptr
int arr[] = {1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15};
TreeNode *root = arrToTree(arr, sizeof(arr) / sizeof(arr[0]));
printf("\n初始化二叉树\n");
printf("二叉树的数组表示:\n");
printArray(arr, sizeof(arr) / sizeof(arr[0]));
printf("二叉树的链表表示:\n");
printTree(root);
vector *vArr = newVector();
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
vectorPushback(vArr, &arr[i], sizeof(int));
}
// 数组表示下的二叉树类
arrayBinaryTree *abt = newArrayBinaryTree(vArr);
// 访问节点
int i = 1;
int l = left(i), r = right(i), p = parent(i);
printf("\n当前节点的索引为 %d值为 %d\n", i, val(abt, i));
printf("其左子节点的索引为 %d值为 %d\r\n", l, val(abt, l));
printf("其右子节点的索引为 %d值为 %d\r\n", r, val(abt, r));
printf("其父节点的索引为 %d值为 %d\r\n", p, val(abt, p));
// 遍历树
vector *res = levelOrder(abt);
printf("\n层序遍历为: ");
printVector(res, printFunc);
delVector(res);
res = preOrder(abt);
printf("前序遍历为: ");
printVector(res, printFunc);
delVector(res);
res = inOrder(abt);
printf("中序遍历为: ");
printVector(res, printFunc);
delVector(res);
res = postOrder(abt);
printf("后序遍历为: ");
printVector(res, printFunc);
delVector(res);
return 0;
}