【算法导论】第12章二叉查找树
2012-06-19 15:40
429 查看
1、问题引入
查找树是一种数据结构,它支持多种动态集合操作,包括构造、查找、插入、删除、寻找最小值、寻找最大值等,其中构造过程主要采用不断插入值来完成。
二叉查找树中的关键字存储方式满足以下性质:设x为二叉查找树中的一个节点,如果y是x的左子树中的一个节点,则y->data < x->data;如果y是x的右子树中的一个节点,则y->data > x->data。
二叉查找树上执行的基本操作的时间与树的高度成正比,对于一棵含n个节点的完全二叉树,这些操作的最坏情况运行时间为o(lgn)。同样的,如果树是含有n个节点的线性链,则这些操作的最坏时间为o(n)。
2、数据结构
二叉查找树是按照二叉树结构来组织的,这样的树可以采用数组来表示,也可以采用链表结构来表示,不过数组表示没有链表结构简单明了,这里采用链表结构来表示,每一个节点就表示一个对象,节点中包含data数据部分、left指针(指向左儿子)、right指针(指向右儿子),如果某个节点的儿子节点不存在,则相应的儿子节点为NULL。
定义为:typedef struct treenode
{
elemType data;
struct treenode *left;
struct treenode *right;
}tree;
3、基本算法
3.1 构造二叉查找树算法
3.2 中序遍历算法
3.3 查找一个给定的关键字所在节点算法
3.4 查找最大和最小关键字元素
3.5 在二叉查找树中插入一个节点
3.6 在二叉查找树中删除一个节点
删除节点的操作稍微复杂一些,要分三种情况:
(a)如果要删除的节点没有子女,则定位到该节点之后直接删除即可。
(b)如果要删除的节点有一个子女,则定位到该节点之后,让节点的父节点直接指向该节点的子节点,然后删除该节点即可。
(c)如果要删除的节点有两个子女,则定位到该节点之后,找出其后继结点,用后继结点的data和附加数据替换该节点的数据,然后删除后继结点(递归调用删除算法)。
具体算法:
4、具体的代码实现:
View Code
5、参考资料:
(1)http://kb.cnblogs.com/a/2336968/
(2)算法导论
查找树是一种数据结构,它支持多种动态集合操作,包括构造、查找、插入、删除、寻找最小值、寻找最大值等,其中构造过程主要采用不断插入值来完成。
二叉查找树中的关键字存储方式满足以下性质:设x为二叉查找树中的一个节点,如果y是x的左子树中的一个节点,则y->data < x->data;如果y是x的右子树中的一个节点,则y->data > x->data。
二叉查找树上执行的基本操作的时间与树的高度成正比,对于一棵含n个节点的完全二叉树,这些操作的最坏情况运行时间为o(lgn)。同样的,如果树是含有n个节点的线性链,则这些操作的最坏时间为o(n)。
2、数据结构
二叉查找树是按照二叉树结构来组织的,这样的树可以采用数组来表示,也可以采用链表结构来表示,不过数组表示没有链表结构简单明了,这里采用链表结构来表示,每一个节点就表示一个对象,节点中包含data数据部分、left指针(指向左儿子)、right指针(指向右儿子),如果某个节点的儿子节点不存在,则相应的儿子节点为NULL。
定义为:typedef struct treenode
{
elemType data;
struct treenode *left;
struct treenode *right;
}tree;
3、基本算法
3.1 构造二叉查找树算法
//构造二叉查找树 tree *makeTree(tree *p) { scanf("%d",&k); while(k!=-1)//以输入-1表示构造结束 { p=insertTreeNode(p,k);//通过插入节点方式构造 scanf("%d",&k); } return(p);//得到树p }
3.2 中序遍历算法
void printTree(tree *t) { if(t) { printTree(t->left); printf("%d ",t->data); printTree(t->right); } }
3.3 查找一个给定的关键字所在节点算法
tree *searchTreeNode(tree *p,elemType k) { if(p==NULL) || k=p->data return p; if(k<p->data) return searchTreeNode(p->left,k); else return searchTreeNode(p->right,k): }
3.4 查找最大和最小关键字元素
//在二叉查找树中查找最小节点 tree *findMinTreeNode(tree *t) { if(t==NULL) //树为空 { printf("error!!"); return NULL; } while(t->left)//二叉查找树中的最小节点在最左边 t=t->left; return(t); } //二叉查找树中的最大节点在最右边,算法类似。。。
3.5 在二叉查找树中插入一个节点
//在二叉查找树中插入节点 tree *insertTreeNode(tree *t,elemType e) { if(t==NULL)//定位到要插入的节点位置t=null { t=(tree *)malloc(sizeof(tree)); if(t==NULL) printf("error!"); t->data=e; t->left=NULL; t->right=NULL; } else if(e<t->data )//节点值小于t节点值 t->left=insertTreeNode(t->left,e); else //节点值不小于t节点值得 t->right=insertTreeNode(t->right,e); return(t);//返回结果 }
3.6 在二叉查找树中删除一个节点
删除节点的操作稍微复杂一些,要分三种情况:
(a)如果要删除的节点没有子女,则定位到该节点之后直接删除即可。
(b)如果要删除的节点有一个子女,则定位到该节点之后,让节点的父节点直接指向该节点的子节点,然后删除该节点即可。
(c)如果要删除的节点有两个子女,则定位到该节点之后,找出其后继结点,用后继结点的data和附加数据替换该节点的数据,然后删除后继结点(递归调用删除算法)。
具体算法:
tree *deleteTreeNode(tree *t,elemType e) { tree *p; if(t==NULL) { printf("error!!!\n"); return NULL; } if(e < (t->data))//e小于t中的data值,则从t的左子树中删除e; t->left=deleteTreeNode(t->left,e); else if(e > (t->data))//e大于t中的data值,则从t的右子树中删除e; t->right=deleteTreeNode(t->right,e); else if((t->left) && (t->right))//找到节点且该节点的左右子树都存在 { p=findMinTreeNode(t->right);//找到后继结点 t->data=p->data;//将后继结点的值赋给t节点 t->right=deleteTreeNode(t->right,t->data);//删除后继结点 } else//找到节点且节点或者只存在一个子节点或者不存在子节点 { p=t; if(t->left==NULL) t=t->right; else if(t->right==NULL) t=t->left; free(p); return(t); } return(t); }
4、具体的代码实现:
View Code
#include<stdlib.h> #include<stdio.h> typedef int elemType; typedef struct treenode { elemType data; struct treenode *left; struct treenode *right; }tree; tree *makeTree(tree *p); void printTree(tree *t); tree *insertTreeNode(tree *t,elemType e); tree *deleteTreeNode(tree *t,elemType e); tree *findMaxTreeNode(tree * t); tree *findMinTreeNode(tree *t); tree *findTreeNode(tree *t,elemType e); //------------------------------------------------- //构造二叉查找树 tree *makeTree(tree *p) { int k; printf("构造树,请输入节点值(以-1结束):\n"); scanf("%d",&k); while(k!=-1) { p=insertTreeNode(p,k); scanf("%d",&k); } printf("\n"); return(p); } //中序遍历二叉查找树 void printTree(tree *t) { if(t) { printTree(t->left); printf("%d ",t->data); printTree(t->right); } } //在二叉查找树中查找最小节点 tree *findMinTreeNode(tree *t) { if(t==NULL) { printf("error!!"); return NULL; } while(t->left) t=t->left; return(t); } //在二叉查找树中查找最大节点 tree *findMaxTreeNode(tree *t) { if(t==NULL) { printf("error!!"); return NULL; } while(t->right) t=t->right; return(t); } //在二叉查找树中插入节点 tree *insertTreeNode(tree *t,elemType e) { if(t==NULL) { t=(tree *)malloc(sizeof(tree)); if(t==NULL) printf("error!"); t->data=e; t->left=NULL; t->right=NULL; } else if(e<t->data ) t->left=insertTreeNode(t->left,e); else t->right=insertTreeNode(t->right,e); return(t); } //在二叉查找树中删除节点 tree *deleteTreeNode(tree *t,elemType e) { tree *p; if(t==NULL) { printf("error!!!\n"); return NULL; } if(e < (t->data))//e小于t中的data值,则从t的左子树中删除e; t->left=deleteTreeNode(t->left,e); else if(e > (t->data))//e大于t中的data值,则从t的右子树中删除e; t->right=deleteTreeNode(t->right,e); else if((t->left) && (t->right))//找到节点且该节点的左右子树都存在 { p=findMinTreeNode(t->right);//找到后继结点 t->data=p->data;//将后继结点的值赋给t节点 t->right=deleteTreeNode(t->right,t->data);//删除后继结点 } else//找到节点且节点或者只存在一个子节点或者不存在子节点 { p=t; if(t->left==NULL) t=t->right; else if(t->right==NULL) t=t->left; free(p); return(t); } return(t); } void main() { int d; tree *p; p=NULL; //----------------------------------------------- p=makeTree(p); printf("构造后的树采用中序遍历结果为:\n"); printTree(p); //----------------------------------------------- printf("插入节点:\n"); printf("请输入要插入的节点值:\n"); scanf("%d",&d); p=insertTreeNode(p,d); printf("插入节点后的树采用中序遍历结果为:\n"); printTree(p); //----------------------------------------------- printf("删除节点:\n"); printf("请输入要删除的节点值:\n"); scanf("%d",&d); p=deleteTreeNode(p,d); printf("删除节点后的树采用中序遍历结果为:\n"); printTree(p); //------------------------------------------------ printf("\n构造树中的最小节点为:\n"); p=findMinTreeNode(p); printf("%d \n",p->data); printf("\n构造树中的最大节点为:\n"); p=findMaxTreeNode(p); printf("%d \n",p->data); }
5、参考资料:
(1)http://kb.cnblogs.com/a/2336968/
(2)算法导论
相关文章推荐
- 二叉查找树——算法导论第12章简易代码实现~
- 算法导论——(2)二叉查找树的实现
- [算法导论 12章] 二叉查找树
- 二叉搜索树(算法导论第12章)
- 【算法导论】学习笔记——第12章 二叉搜索树
- 最优二叉查找树 算法导论216
- 二叉查找树(binary search tree (BST))--算法导论示例
- 二叉查找树 算法导论笔记
- 算法导论-第12章-二叉搜索树:随机二叉搜索树数据结构C++实现(前中后序遍历,插入,搜索,前后毗邻元素,最大最小值)
- 二叉排序树(Binary Sort Tree,二叉查找树,二叉搜索树)--【算法导论】
- 算法导论15.5 最优二叉查找树
- 二叉查找树(binary search tree (BST))--算法导论示例
- 最优二叉查找树详解(算法导论学习笔记)
- 【算法导论】动态规划之最优二叉查找树
- [算法导论]二叉查找树的实现 @ Python
- 【算法导论】动态规划之最优二叉查找树
- 二叉查找树相关算法实现(算法导论12章)
- 二叉查找树(来自算法导论)