树
创建: 2018/04/13
完成: 2018/05/14
| 树 | ||||||||||||||||
|
● 类似于链表,但每一个节点指向多个节点。 ● 非线性数据结构(元素间的顺序不重要), 顺序重要的用链表, 堆, 队列等线性数据结构 |
||||||||||||||||
| 树的术语 | ||||||||||||||||
| 根 | 根节点(没有父节点) | |||||||||||||||
| 边 | 从父节点到子节点的连线 | |||||||||||||||
| 叶 | 不含子节点的节点 | |||||||||||||||
| 兄弟 | 父节点相同的节点 | |||||||||||||||
| 祖先, 子孙 | 能连过去的 | |||||||||||||||
| 层次(level) |
该层所有节点的集合 根为层次0 |
|||||||||||||||
| 深度 |
根到该层的层数差 |
|||||||||||||||
| 高度 |
从该节点到可到的最下层节点的层数差 |
|||||||||||||||
| 树的高度 |
根节点到最深层次的层数差 |
|||||||||||||||
| 节点的大小 | 算上自己的所有子孙数 | |||||||||||||||
| 歪树(skew tree) | 除了叶(叶没有子节点)以外所有节点只有一个子节点 | |||||||||||||||
| 二叉树 | ||||||||||||||||
| 定义 |
● 节点最多只能包含2个子节点的树构造 ● 可以看做根, 左二叉树, 右二叉树 |
|||||||||||||||
| 二叉树的型 | ||||||||||||||||
| 严密二叉树 | 子节点数要么0要么2 | |||||||||||||||
| 完全二叉树 | 子节点数全是2, 所有叶的高度相同 | |||||||||||||||
| 全二叉树 | 子节点数全是2, 所有叶的高度为h或h-1 | |||||||||||||||
| 二叉树的性质 | ||||||||||||||||
| 二叉树构造 |
struct BinaryTreeNode { int data; struct BinaryTreeNode *left; struct BinaryTreeNode *right; }
|
|||||||||||||||
| 二叉树运算 |
● 基本运算 - 插入元素 - 删除元素 - 搜索元素 - 横断 ● 辅助运算 - 求木的大小(元素数量) - 求和最大的层次 - 对两个求点求最近共同祖先 |
|||||||||||||||
| 二叉树应用 |
● 编译器 ● 数据压缩算法使用的哈夫曼编码(Huffman coding) ● 对元素的组合进行搜索, 插入, 删除的二叉排序树(二叉探索树) O(logn)(平均) ● 对元素的组合进行最大值(最小值)搜索, 删除的带优先度队列(PQ) |
|||||||||||||||
| 二叉树遍历 | ||||||||||||||||
| 前序遍历(DLR) |
非递归版需要堆, C语言没有堆标准库, 以后有空补上 //------------------------------------------------ // 前序遍历 DLR //------------------------------------------------ // 递归版 void preOrder(struct BinaryTreeNode *root) { if (root) { printf("处理%d\n中", root->data); preOrder(root->left); preOrder(root->right); } }
|
|||||||||||||||
| 中序遍历(LDR) |
非递归版需要堆, C语言没有堆标准库, 以后有空补上 //------------------------------------------------ // 中序遍历 LDR //------------------------------------------------ // 递归版 void inOrder(struct BinaryTreeNode *root) { if (root) { inOrder(root->left); printf("处理%d\n中", root->data); inOrder(root->right); } }
|
|||||||||||||||
| 后序遍历 (LRD) |
非递归版需要堆, C语言没有堆标准库, 以后有空补上
//------------------------------------------------ // 后序遍历 LRD //------------------------------------------------ // 递归版 void postOrder(struct BinaryTreeNode *root) { if (root) { postOrder(root->left); postOrder(root->right); printf("处理%d\n中", root->data); } }
|
|||||||||||||||
| 层次遍历 |
Queue自己实现去吧 //------------------------------------------------ // 层次遍历 //------------------------------------------------ // 层次遍历使用的queue struct S6_Queue { int front, rear; int capacity; int *array; }; struct S6_Queue *S6CreateQueue() {return NULL;} int S6IsEmptyQueue(struct S6_Queue *queue) { return rand()%2;} void S6EnQueue(struct BinaryTreeNode *data, struct S6_Queue *queue) {} struct BinaryTreeNode *S6DeQueue() { return NULL; } void S6DeleteQueue(struct S6_Queue *queue) {}; // 层次遍历 void levelOrder(struct BinaryTreeNode *root) { struct S6_Queue *queue = S6CreateQueue(); struct BinaryTreeNode *temp; if (root == NULL) { return; } S6EnQueue(root, queue); while (!S6IsEmptyQueue(queue)) { temp = S6DeQueue(); // 处理当前node if (temp->left) { S6EnQueue(temp->left, queue); } if (temp->right) { S6EnQueue(temp->right, queue); } } S6DeleteQueue(queue); }
|
|||||||||||||||
| 一般树(N叉树) | ||||||||||||||||
| 数据结构 |
// N叉树数据结构 struct TreeNode { int data; struct TreeNode *firstChild; // 左侧子节点 struct TreeNode *nextSibling; // 同层次右边一个节点 }
|
|||||||||||||||
| 线索二叉树遍历 | ||||||||||||||||
| 结构 |
左线索指向遍历顺序下前一个, 右线索指向遍历顺序下后一个 struct ThreadedBinaryTreeNode { struct ThreadedBinaryTreeNode *left; int LTag; int data; int RTag; struct ThreadedBinaryTreeNode *right; }
|
|||||||||||||||
| 分类 |
|
|||||||||||||||
| 二叉树与线索二叉树的区别 |
|
|||||||||||||||
| 中序遍历 |
dummy节点: left | LTag | data | RTag | right
struct ThreadedBinaryTreeNode { struct ThreadedBinaryTreeNode *left; int LTag; // 0: 线索指针, 1: 子节点指针 int data; int RTag; struct ThreadedBinaryTreeNode *right; }; //------------------------------------------------ // 中序遍历 //------------------------------------------------ // 搜索中序遍历的下一个节点 struct ThreadedBinaryTreeNode *inOrderSuccessor(struct ThreadedBinaryTreeNode *p) { struct ThreadedBinaryTreeNode *position; if (p->RTag == 0) { // 右子节点不存在, 返回上层节点 return p->right; } else { // 右侧子节点存在 position = p->right; while (position->LTag == 1) { position = position->left; } return position; } } // dummy节点: RTag恒为1, right指向自身 // 中序遍历 // 方法1 void inorderTraversal(struct ThreadedBinaryTreeNode *root) { // root是dummy节点 struct ThreadedBinaryTreeNode *current = inOrderSuccessor(root); while (current != root) { current = inOrderSuccessor(current); printf("data: %d\n", current->data); } } // 方法2 void inorderTraversalV2(struct ThreadedBinaryTreeNode *root) { struct ThreadedBinaryTreeNode *current = root; while (1) { if (current == root) { return; } current = inOrderSuccessor(current); printf("data: %d\n", current->data); } }
|
|||||||||||||||
| 向线索二叉树插入节点 | ||||||||||||||||
| 表达式树(expression tree) | ||||||||||||||||
| 概述 | 叶节点是被运算值, 分支节点(非终端节点)是运算符 | |||||||||||||||
|
struct BinaryTreeNode *buildExpressionTree(char postfixExpression[], int size) { struct S9Stack *stack = S9CreateStack(); for (int i = 0; i < size; i++) { if (!isOperater(postfixExpression[i])) { struct BinaryTreeNode *newNode = (struct BinaryTreeNode *)malloc(sizeof(struct BinaryTreeNode)); if (!newNode) { printf("memory error\n"); return NULL; } newNode->data = postfixExpression[i]; newNode->left = newNode->right = NULL; S9Push(stack, newNode); } else { struct BinaryTreeNode *t2 = S9Pop(stack), *t1 = S9Pop(stack); struct BinaryTreeNode *newNode = (struct BinaryTreeNode *)malloc(sizeof(struct BinaryTreeNode)); if (!newNode) { printf("memory error\n"); return NULL; } newNode->left = t1; newNode->right = t2; newNode->data = postfixExpression[i]; S9Push(stack, newNode); } } return stack; }
|
||||||||||||||||
| XOR树 | ||||||||||||||||
| 二叉搜索树 | ||||||||||||||||
| BST(Binary Search Tree) | ||||||||||||||||
| 性质 | 左子节点小比当前小, 右子节点比当前大 | |||||||||||||||
| 节点声明 |
//------------------------------------------------ // 二叉搜索树节点声明 //------------------------------------------------ // 和普通二叉树没有区别 struct BinarySearchTreeNode { int data; struct BinarySearchTreeNode *left; struct BinarySearchTreeNode *right; };
|
|||||||||||||||
| 运算 |
|
|||||||||||||||
| 注 |
● 中序遍历相当于升序排序 ● 一般处理顺序: 左->根->右 一般只需要处理根节点 ● 搜索更简单, 左小右大所以只需考虑半边 |
|||||||||||||||
| 搜索元素 |
//------------------------------------------------ // 搜索元素 //------------------------------------------------ // 方法1 struct BinarySearchTreeNode *find(struct BinarySearchTreeNode *root, int data) { if (root == NULL) { return NULL; } if (data < root->data) { return find(root->left, data); } else if (data > root->data) { return find(root->right, data); } else { return root; } } // 方法2 struct BinarySearchTreeNode *findV2(struct BinarySearchTreeNode *root, int data) { while (root) { if (data == root->data) { return root; } else if (data > root->data) { root = root->right; } else { root = root->left; } } return NULL; } // 个人方法 struct BinarySearchTreeNode *findV3(struct BinarySearchTreeNode *root, int data) { struct BinarySearchTreeNode *current = root; if (root == NULL) { return NULL; } while (1) { if (data == current->data) { return current; } else if (data > current->data) { current = current->right; } else { current = current->left; } if (current == NULL) { return NULL; } } }
|
|||||||||||||||
| 搜索最小元素 |
//------------------------------------------------ // 搜索最小元素 //------------------------------------------------ // 递归版 struct BinarySearchTreeNode *findMin(struct BinarySearchTreeNode *root) { if (root == NULL) { return NULL; } if (root->left) { return findMin(root->left); } else { return root; } } // 非递归版 struct BinarySearchTreeNode *findMinV2(struct BinarySearchTreeNode *root) { if (root == NULL) { return NULL; } while (root->left) { root = root->left; } return root; } struct BinarySearchTreeNode *findMinV3(struct BinarySearchTreeNode *root) { if (root == NULL) { return NULL; } while (1) { if (root->left) { root = root->left; } else { break; } } return root; }
|
|||||||||||||||
| 搜素最大元素 |
//------------------------------------------------ // 搜索最大元素 //------------------------------------------------ // 递归版 struct BinarySearchTreeNode *findMax(struct BinarySearchTreeNode *root) { if (root == NULL) { return NULL; } if (root->right == NULL) { return root; } else { return findMax(root->right); } } // 非递归版 struct BinarySearchTreeNode *findMaxV2(struct BinarySearchTreeNode *root) { if (root == NULL) { return NULL; } while (root->right) { root = root->right; } return root; } struct BinarySearchTreeNode *findMaxV3(struct BinarySearchTreeNode *root) { if (root == NULL) { return NULL; } while (1) { if (root->right) { root = root->right; } else { return root; } } }
|
|||||||||||||||
| 插入元素 |
//------------------------------------------------ // 插入元素 //------------------------------------------------ // 递归版 struct BinarySearchTreeNode *insert(struct BinarySearchTreeNode *root, int data) { if (root == NULL) { // 树不存在则新建树 root = (struct BinarySearchTreeNode *)malloc(sizeof(struct BinarySearchTreeNode)); if (root == NULL) { // 生成树失败 return NULL; } root->data = data; root->left = root->right = NULL; return root; } else { if (data < root->data) { root->left = insert(root->left, data); } else if (data > root->data) { root->right = insert(root->right, data); } } return root; } // 非递归版 struct BinarySearchTreeNode *insertV2(struct BinarySearchTreeNode *root, int data) { if (root == NULL) { root = (struct BinarySearchTreeNode *)malloc(sizeof(struct BinarySearchTreeNode)); if (root == NULL) { return NULL; } root->data = data; root->left = root->right = NULL; return root; } else { struct BinarySearchTreeNode *current = root; while (1) { if (data > current->data) { if (current->right) { current = current->right; } else { current->right = (struct BinarySearchTreeNode *)malloc(sizeof(struct BinarySearchTreeNode)); current->right->data = data; current->right->left = current->right->right = NULL; return root; } } else if (data < current->data) { if (current->left) { current = current->left; } else { current->left = (struct BinarySearchTreeNode *)malloc(sizeof(struct BinarySearchTreeNode)); current->left->data = data; current->left->left = current->left->right = NULL; return root; } } } } }
|
|||||||||||||||
| 删除元素 |
//------------------------------------------------ // 删除元素 //------------------------------------------------ // 递归版 struct BinarySearchTreeNode *delete(struct BinarySearchTreeNode *root, int data) { struct BinarySearchTreeNode *temp; if (root == NULL) { return NULL; } if (data < root->data) { root->left = delete(root->left, data); } else if (data > root->data) { root->right = delete(root->right, data); } else { // 找到了需要删除的元素 if (root->left && root->right) { // 子节点有两个 //可以把用左侧最大或右侧最小替代当前元素 temp = findMax(root); root->data = temp -> data; root->left = delete(root->left, root->data); } else if (!root->left && !root->right) { // 子节点0个 temp = root; free(temp); } else { // 子节点1个 if (root->left == NULL) { root = root->right; } else if (root->right == NULL) { root = root->left; } temp = root; free(temp); } } return root; }
|
|||||||||||||||
| AVL树 | ||||||||||||||||
| 树的其他形式 | ||||||||||||||||

浙公网安备 33010602011771号