树的定义
树是由n(n大于等于0)个节点构成的集合,当n是0时则是空集,若是非空,则树是由一个称为根(root)的节点r以及0个或者多个非空的子树组成。这些子树中每一颗的根都被来自根r的一条有向边(edge)连接。
每一颗子树的根叫做根r的儿子(child),而r是每一颗子树的根的父亲(parent)

没有儿子的节点为叶节点
具有相同父亲的位兄弟节点
对于任意节点,节点的深度为从根节点到该节点的唯一路径的长
二叉树(Binary Tree)
二叉树是一颗树,是一个有穷的节点的集合,或者为空,或者包含一个树根与两个不相交的二叉树称为左、右子树。
树节点 struct定义
#include <stdio.h>#include <stdlib.h>typedef struct TreeNode BinaryTreeNode;typedef BinaryTreeNode *PtrNode;struct TreeNode{/* data */int data;PtrNode left;PtrNode right;};PtrNode createTreeNode(const int data){PtrNode node;node = (PtrNode)malloc(sizeof(node));if (node == NULL){printf("内存分配失败\n");exit(EXIT_FAILURE);}node->left = node->right = NULL;node->data = data;return node;};
插入
PtrNode insert(PtrNode node, const int data){if (node == NULL){node = createTreeNode(data);}else if (node->data < data){node->right = insert(node->right, data);}else if (node->data > data){node->left = insert(node->left, data);}return node;}
遍历
先序遍历(preorder traversal)
// 先序遍历void preOrder(PtrNode node){if (node != NULL){printf(" node data = %d\n", node->data);preOrder(node->left);preOrder(node->right);}}
中序遍历(inorder traversal)
void inOrder(PtrNode node){if (node != NULL){inOrder(node->left);printf(" node data = %d\n", node->data);inOrder(node->right);}}
后序遍历 (postorder traversal)
// 后续遍历void postOrder(PtrNode node){if (node != NULL){postOrder(node->left);postOrder(node->right);printf(" node data = %d\n", node->data);}};
层序遍历(levelorder traversal) 也是树的深度优先搜索(Breadth-first search)
- 使用函数打印层级 ```c // 层序遍历 也是 BFS void levelorder(PtrNode node); // 打印当前层级 void currentLevel(PtrNode node, int level);
// 获取高度 int height(PtrNode node);
// 层序遍历 void levelorder(PtrNode node) { int h = height(node); int i; for (i = 0; i < h; i++) { / code / currentLevel(node, i); } }
void currentLevel(PtrNode node, int level) { if (node != NULL) { if (level == 1) { printf(“level order data = %d\n”, node->data); } else if (level > 1) {
currentLevel(node->left, level - 1);currentLevel(node->right, level - 1);}}
};
int height(PtrNode node) { if (node == NULL) { return 0; }; int leftHeight = height(node->left); int rightHeight = height(node->right); // 获取较大的值 if (leftHeight > rightHeight) { return leftHeight + 1; } return rightHeight + 1; }
2. 使用队列辅助```javaprivate void levelOrder(BinaryTreeNode root) {Queue<BinaryTreeNode> dQueue = new LinkedList<>();dQueue.add(root);while (!dQueue.isEmpty()) {BinaryTreeNode node = dQueue.poll();System.out.println("data = " + node.data);if (node.left != null) {dQueue.add(node.left);}if (node.right != null) {dQueue.add(node.right);}}}
二叉搜索树(Binary Search Tree)
一颗二叉搜索树是一颗二叉树,他可以为空,如果他不为空那么它满足下述的条件:
1.每个元素都有一个键值,并且所有的键值不相同
2.左子树(如果有)的键值都小于树根的键值
3.右子树(如果有)的键值都大于树根的键值
4.左右子树也都是二叉搜索树
一种对已排序数据进行快速搜索、插入、删除的树
#include <stdio.h>#include <stdlib.h>typedef struct TreeNode BinaryTreeNode;typedef BinaryTreeNode *PtrNode;typedef BinaryTreeNode *Position;typedef BinaryTreeNode *SearchTree;struct TreeNode{/* data */int data;PtrNode left;PtrNode right;};PtrNode createTreeNode(const int data){PtrNode node;node = (PtrNode)malloc(sizeof(node));if (node == NULL){printf("内存分配失败\n");exit(EXIT_FAILURE);}node->left = node->right = NULL;node->data = data;return node;};// 查找指定数据的节点Position find(int x,SearchTree tree);// 获取最小节点Position findMin(SearchTree tree);// 获取最大节点Position findMax(SearchTree tree);// 插入SearchTree insert(int x,SearchTree tree);// 删除指定元素SearchTree deleteEl(int x,SearchTree tree);
查找
//利用递归查找指定元素Position find(int x, SearchTree tree){if (tree == NULL){return NULL;}if (x < tree->data){return find(x, tree->left);}else if (x > tree->data){return find(x, tree->right);}return tree;}
查找最小
// 递归查找左节点 为最小Position findMin(SearchTree tree){if (tree == NULL)return NULL;if (tree->left == NULL)return tree;return findMin(tree->left);}
查找最大
// 循环查找右节点 为最大Position findMax(SearchTree tree){if (tree != NULL){while (tree->right != NULL){tree = tree->right;}}return tree;}
插入
// 插入数据SearchTree insert(int data, SearchTree tree){if (tree == NULL){tree = createTreeNode(data);}else if (tree->data < data){tree->right = insert(data, tree->right);}else if (tree->data > data){tree->left = insert(data, tree->left);}return tree;}
删除
SearchTree deleteEl(int x, SearchTree tree){Position temp;if (tree != NULL){// 二分查找if (tree->data > x){tree->left = deleteEl(x, tree->left);}else if (tree->data < x){tree->right = deleteEl(x, tree->right);}// 要删除的节点 两个子节点都不为空else if (tree->left && tree->right){/* 找到最小的右侧子节点 替换到当前位置 */temp = findMin(tree->right);tree->data = temp->data;// 再将最小节点的删除tree->right = deleteEl(tree->data, tree->right);}else{// 这里可能是只有一个节点或者0个节点temp = tree;if (tree->left == NULL){tree = tree->right;}else if (tree->right == NULL){tree = tree->left;}free(temp);}}return tree;}
