搜索二叉树
Posted 2018zxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索二叉树相关的知识,希望对你有一定的参考价值。
思路:
(1)搜索二叉树的结构就是二叉树的左右两个节点,所有左子节点的值小于右子节点的值,然后还要有一个lazy标志,用于lazy删除。
(2)搜索二叉树主要有一下几个操作:建立搜索二叉树;建立空树;查找x的位置;查找最大,最小值的位置;
插入节点,删除节点;打印二叉树;
(3)建立搜索二叉树,不同于链表的建立,不用带头结点,所以直接插入就行了。
(4)建立空树:递归删除每个节点,通过后序遍历,先找到然后再删除。
(5)查找x的位置:递归查找,如果x小于当前节点的值就在左子树中查找,否则在右子树中查找。
(6)查找最大,最小值:二叉查找时的最左节点就是最小值,最右子节点就是最大值;
查找过程可以用递归或者非递归两种方式实现
eg:查找最小值,不断向左递归查找;或者将根节点的所有左子树视为一个链表,不断指向左结点来实现。
(7)插入:如果即将插入的节点是空,就分配内存,并且插入节点,
如果不是空节点,比较当前节点的值与将要插入的值的大小,再向左向右递归插入。(每次都要返回T的值,返回插入结束后的树,后面的删除操作同理)。
(8)删除:
如果删除的节点数量较小,直接用lazy标记一下就行了。
如果删除数量较大,就要判断删除的是哪一个节点。
叶子节点:直接删除;
只有一个子节点的节点:删除让当前节点变为它的子节点
有两个子节点的节点:先寻找次节点的右子树的最小值,然后将此节点的值替换为右子树的最小值,再递归删除右子树的最小值。
(9)打印二叉树:
前序遍历,中序遍历,后序遍历。
注意:
(1)查找,删除时判断一下是否为空,如果为空就返回
(2)搜索二叉树的中序遍历是x从小到大的排序
(3)搜索二叉树的大部分操作是O(logN)级别的,但是,如果输入5,4,3,2,1就可能退化为一个链表,就并不高效了,
所以应该使二叉树保持平衡状态,降低它的深度,就可以用到AVL树。
(4)删除和查找时注意二叉树的返回。
#include<stdio.h> #include<stdlib.h> struct Node{ int x,lazy; struct Node *Left,*Right; }; typedef struct Node *SearchTree; typedef SearchTree Position; SearchTree MakeEmpty(SearchTree T) { if(T!=NULL) { MakeEmpty(T->Left); MakeEmpty(T->Right); free(T); } return NULL; } SearchTree Find(int x,SearchTree T) { if(T==NULL) return NULL; else if(x<T->x) return Find(x,T->Left); else if(x>T->x) return Find(x,T->Right); else return T; } SearchTree FindMin1(SearchTree T) { if(T==NULL) return NULL; else if(T->Left==NULL) return T; else return FindMin1(T->Left); } SearchTree FindMin2(SearchTree T) { if(T!=NULL) { while(T->Left!=NULL) T=T->Left; } return T; } SearchTree FindMax1(SearchTree T) { if(T==NULL) return NULL; else if(T->Right==NULL) return T; else return FindMax1(T->Right); } SearchTree FindMax2(SearchTree T) { if(T!=NULL) { while(T->Right!=NULL) T=T->Right; } return T; } SearchTree Insert(int x,SearchTree T) { if(T==NULL) { T=(SearchTree)malloc(sizeof(struct Node)); if(T==NULL) printf("Out of Space!!! "); else { T->x=x; T->Left=NULL; T->Right=NULL; } } else if(x<T->x) T->Left=Insert(x,T->Left); else T->Right=Insert(x,T->Right); return T; } SearchTree Delete(int x,SearchTree T) { SearchTree tp; if(T==NULL) printf("Empty SearchTree "); else if(x<T->x) T->Left=Delete(x,T->Left); else if(x>T->x) T->Right=Delete(x,T->Right); else { if(T->Left&&T->Right) { tp=FindMin1(T->Right); T->x=tp->x; T->Right=Delete(tp->x,T->Right); } else { tp=T; if(T->Left==NULL) T=T->Right; else if(T->Right==NULL) T=T->Left; free(tp); } } return T; } SearchTree Delete_Lazy(int x,SearchTree T) { if(T==NULL) printf("Empty SearchTree!!! "); else if(x<T->x) T->Left=Delete(x,T->Left); else if(x>T->x) T->Right=Delete(x,T->Right); else { T->lazy=-1; } return T; } void Print(SearchTree T) { if(T!=NULL) { Print(T->Left); printf("%d ",T->x); Print(T->Right); } } int main(void) { int n,i,x; SearchTree root,p; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&x); root=Insert(x,root); } Print(root); printf(" "); root=Delete(3,root); Print(root); return 0; }
以上是关于搜索二叉树的主要内容,如果未能解决你的问题,请参考以下文章
二叉树进阶题------二叉树的构建及遍历;二叉搜索树转换成排序双向链表;二叉树创建字符串
二叉树进阶题------二叉树的构建及遍历;二叉搜索树转换成排序双向链表;二叉树创建字符串