二叉搜索树-《算法导论》学习笔记十一
来源:互联网 发布:订货软件 编辑:程序博客网 时间:2024/06/08 02:20
二叉搜索树是以一颗二叉树来组织的,每个节点除数据外,还包括三个分别指向父结点、左孩子、右孩子的指针,二叉搜索树有个特性:某个结点root的左子树的某个节点x的关键值小于等于root结点右子树某个结点y的关键值。
二叉搜索树有几个操作:
1、查找
查找与给定关键值相等的结点
2、遍历
前序、中序、后序遍历输出
3、从某结点出发,寻找子树中最小关键值的结点
4、从某结点出发,寻找子树中最大关键值的结点
5、以某种遍历方式的次数,寻找某结点的前驱结点和后继结点
例如中序遍历的顺序为123456,则4结点的前驱为3,后继为5
6、插入结点
7、删除结点
删除某个结点后,要把它的后继结点补在删除的位置上,要注意:
- 如果结点没有孩子结点,那么只是简单地将它删除,并删改它的父结点的孩子指针指向它
- 如果结点只有一个孩子,那么将它孩子提升到它的位置,并修改它的父结点的孩子指针指向它
如果节点有两个孩子,那么寻找它的后继(按中序遍历来说一定在右子树),并让后继占据它的位置,后继(按中序遍历来说一定没有左子树)的子树提升到后继的位置
情况如上,具体删除时如何替换,又有不同情况:
如果结点只有左或孩子,用孩子替换结点
- 如果结点有左右两个孩子,那么要查找结点的后继:(1)、如果后继是结点的右孩子,用后继替换结点,并留下后继的右孩子;(2)、后继位于结点的右子树,但并不是结点的右孩子,则,先用后继的右孩子替换后继,再用后继替换结点
代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>typedef struct biSearchTreeNode { int key; struct biSearchTreeNode *parent; struct biSearchTreeNode *left; struct biSearchTreeNode *right;}biSearchTreeNode;typedef struct biSearchTree { int node_num; int height; biSearchTreeNode *root;}biSearchTree;int random_num(){ int a = 1; int b = 100; return rand() % ( b - a ) + a;}void postorder_tree_free( biSearchTreeNode *root ){ if ( root != NULL ) { postorder_tree_free( root->left ); postorder_tree_free( root->right ); free( root ); }}void inorder_tree_walk( biSearchTreeNode *root ){ if ( root != NULL ) { inorder_tree_walk( root->left ); printf("%d ", root->key); inorder_tree_walk( root->right ); }}void preorder_tree_walk( biSearchTreeNode *root ){ if ( root != NULL ) { printf("%d ", root->key); preorder_tree_walk( root->left ); preorder_tree_walk( root->right ); }}void postorder_tree_walk( biSearchTreeNode *root ){ if ( root != NULL ) { postorder_tree_walk( root->left ); postorder_tree_walk( root->right ); printf("%d ", root->key); }}void print_tree( biSearchTree *tree ){ printf("中序:"); inorder_tree_walk( tree->root ); printf("\n"); printf("前序:"); preorder_tree_walk( tree->root ); printf("\n"); printf("后序:"); postorder_tree_walk( tree->root ); printf("\n\n");}biSearchTreeNode *tree_search_recursion( biSearchTreeNode *root, int key ){ if ( root == NULL || key == root->key ) { return root; } if ( key < root->key ) return tree_search_recursion( root->left, key ); else return tree_search_recursion( root->right, key );}biSearchTreeNode *tree_search( biSearchTreeNode *root, int key ){ while ( root != NULL && key != root->key ) { if ( key < root->key ) root = root->left; else root = root->right; } return root;}biSearchTreeNode *tree_minimum( biSearchTreeNode *root ){ while ( root->left != NULL ) { root = root->left; } return root;}biSearchTreeNode *tree_maximum( biSearchTreeNode *root ){ while ( root->right != NULL ) { root = root->right; } return root;}// 找前驱 即中序遍历的前一个位置值biSearchTreeNode *tree_predecessor( biSearchTreeNode *node ){ if ( node->left != NULL ) return tree_maximum( node->left ); biSearchTreeNode *p = node->parent; while ( p != NULL && node == p->left ) { node = p; p = p->parent; } return p;}// 找后继 即中序遍历的后一个位置值biSearchTreeNode *tree_successor( biSearchTreeNode *node ){ if ( node->right != NULL ) return tree_minimum( node->right ); biSearchTreeNode *p = node->parent; while ( p != NULL && node == p->right ) { node = p; p = p->parent; } return p;}void tree_insert( biSearchTree *tree, biSearchTreeNode *node ){ biSearchTreeNode *root = tree->root; biSearchTreeNode *p = NULL; biSearchTreeNode *q = root; while ( q != NULL ) { p = q; if ( node->key < q->key ) q = q->left; else q = q->right; } node->parent = p; if ( p == NULL ) { tree->root = node; } else if ( node->key < p->key ) p->left = node; else p->right = node;}void transplant( biSearchTree *tree, biSearchTreeNode *node_a, biSearchTreeNode *node_b ){ if ( node_a->parent == NULL ) tree->root = node_b; else if ( node_a == node_a->parent->left ) node_a->parent->left = node_b; else node_a->parent->right = node_b; if ( node_b != NULL ) node_b->parent = node_a->parent;}void tree_delete( biSearchTree *tree, biSearchTreeNode *node ){ if ( node->left == NULL ) transplant( tree, node, node->right ); else if ( node->right == NULL ) transplant( tree, node, node->left ); else { biSearchTreeNode *p = tree_minimum( node->right ); if ( p->parent != node ) { transplant( tree, p, p->right ); p->right = node->right; p->right->parent = p; } transplant( tree, node, p ); p->left = node->left; p->left->parent = p; } free( node );}void free_tree( biSearchTree *tree ){ biSearchTreeNode *root = tree->root; postorder_tree_free( root ); free( tree );}int main( int argc, char **argv ){ srand((int)time(NULL)); int i = 10; int len = 10; int arr[10] = {10,4,15,14,5, 2,8,13,1,19}; biSearchTree *tree = ( biSearchTree * )malloc( sizeof(biSearchTree) ); tree->node_num = 0; tree->height = 0; for ( i = 0; i < len; i++ ) { biSearchTreeNode *node = ( biSearchTreeNode * )malloc( sizeof(biSearchTreeNode) ); //node->key = random_num(); node->key = arr[i]; node->parent = NULL; node->left = NULL; node->right = NULL; tree_insert( tree, node ); } print_tree( tree ); for ( i = 0; i < len; i++ ) { biSearchTreeNode *pre = tree_predecessor( tree_search(tree->root, arr[i]) ); biSearchTreeNode *post = tree_successor( tree_search(tree->root, arr[i]) ); printf("\n"); if ( pre != NULL ) printf("查找%d的中序遍历前驱为:%d\n", arr[i], pre->key); else printf("查找%d的中序遍历前驱为空!\n", arr[i]); if ( post != NULL ) printf("查找%d的中序遍历后继为:%d\n", arr[i], post->key); else printf("查找%d的中序遍历后继为空!\n", arr[i]); } biSearchTreeNode *delete_node = tree_search( tree->root, 4 ); if ( delete_node != NULL ) { tree_delete( tree, delete_node ); } printf("\n删除%d的节点后中序遍历顺序为:", 4); inorder_tree_walk( tree->root ); printf("\n"); delete_node = tree_search( tree->root, 15 ); if ( delete_node != NULL ) { tree_delete( tree, delete_node ); } printf("\n删除%d的节点后中序遍历顺序为:", 15); inorder_tree_walk( tree->root ); printf("\n"); free_tree( tree ); return 0;}
0 0
- 二叉搜索树-《算法导论》学习笔记十一
- 算法导论笔记:12二叉搜索树
- 算法导论学习之--二叉搜索树
- 算法笔记十一:二叉树之搜索二叉树
- 算法导论-----二叉搜索树
- 算法导论-----------二叉搜索树
- 算法导论 二叉搜索树
- 算法导论--二叉搜索树
- 【算法导论】二叉搜索树
- 算法导论二叉搜索树
- 算法导论 二叉搜索树
- 算法导论二叉搜索树
- 算法导论 二叉搜索树
- 《算法导论》学习笔记(3)——二叉搜索树
- 《算法导论》学习笔记(3)——二叉搜索树
- 《算法导论》笔记--二叉搜索树
- 《算法导论》第12章 二叉搜索树 个人笔记
- 《算法导论》学习笔记之Chapter12二叉树基本特点,及二叉搜索树(查找树)
- 数据结构—栈应用(二)括号比配问题
- Part15
- 代码风格
- 查询表空间使用率的sql
- 单调队列优化DP
- 二叉搜索树-《算法导论》学习笔记十一
- Code Jam 2017 Qualification Round Problem A. Oversized Pancake Flipper
- 路径中 使用斜杠/和反斜杠\的区别
- [unity3D基础篇02]必备的3D数学基础1
- C++ #pragma pack()解析
- python中flask 常见问题
- Java异常 相关问题
- Code Jam 2017 Qualification Round Problem B. Tidy Numbers
- 篇章结构类型、层次及分析模式研究