博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
# 学习以及成为想要成为的人day18
阅读量:3969 次
发布时间:2019-05-24

本文共 2684 字,大约阅读时间需要 8 分钟。

排序算法之二叉排序树

写在前面

​ 这个学期本是想着好好把数据结构过一遍,以为看完了就基本可以刷LeetCode,唉,后来发现自己的进度太慢了,现在学的一知半解,在树和图那两节的基本数据结构和算法都没有亲自实现,虽然大体内容都看懂了,但是自己实际写代码确实头疼,暂时就先把后面比较容易实现的算法先写完。

​ 这次实现的数据结构是二叉排序树,是非常常用的数据结构了。查找这一章比较重要的就是二分查找了,二分查找的算法函数替我也写过,如下:

#include
#include
/*二分查找算法*/int binarySearch(int *array,int arraySize,int val){
int low=0,high=arraySize,mid; if(arraySize<=0) return -1; while(low<=high){
mid=(low+high)/2; if(val==array[mid]) return mid; if(val>array[mid]) low=mid+1; if(val

​ 其实二分查找理解起来不难,和我们日常猜数游戏过程很像,这种算法的时间复杂度是O(log2N),但是基于线性数据结构的二分查找实现简单,进行删除和插入操作却很难,而且输入的数据必须按顺序,不然无法查找,所以就引入了二叉排序树,这种非常有用的数据结构。

代码如下

/*C语言实现二叉排序树的基本操作*/#include
#include
#include
#define TRUE 1#define FALSE 0/*二叉树的结构*/typedef struct BiTNode{
int data;struct BiTNode *lchird,*rchild;}BiTNode,*BiTree;/*递归查找二叉排序树T否存在值key*/int SearchBST(BiTree T,int key,BiTree f,BiTree *p){
if(!T){
*p=f; return FALSE;//查找不成功的情况 } else if(key==T->data){
*p=T; return TRUE;//查找成功的情况 } else if(key
data){
return SearchBST(T->lchird,key,T,p);//在左子树里继续寻找 } else return SearchBST(T->rchild,key,T,p);//在右子树里继续寻找}/*二叉排序树的插入操作*/void InsertBST(BiTree *T,int key){
BiTree p,s;if(!SearchBST(*T,key,NULL,&p)){
//二叉排序树里没有key这个元素s=(BiTree)malloc(sizeof(BiTNode));s->data=key;s->lchird=s->rchild=NULL;if(!p) *T=s;//插入s为根节点else if(key
data) p->lchird=s;//插入s为左孩子else p->rchild=s;//插入s为右孩子}}void Delete(BiTree *p){
BiTree q,s; if((*p)->rchild==NULL){
//右子树为空只需重新连接它的左子树 q=*p; *p=(*p)->lchird; free(q); } else if((*p)->lchird==NULL){
//左子树为空连接它的右子树 q=*p; *p=(*p)->rchild; free(q); } else{
/* 左右子树均不为空,有两种解决方案 1、 以待删节点的前趋值(左子树中最大的节点)替换之,然后再删除前趋节点 2、 以待删节点的后继值(右子树中最小的节点)替换之,然后再删除后继节点 */ q=*p; s=(*p)->lchird; while(s->rchild){
//找到右子树最大的节点值 q=s; s=s->rchild; } (*p)->data=s->data;//值替换 if(q!=*p) q->rchild=s->lchird;//重接q的右子树 else q->lchird=s->lchird;//重接q的左子树 free(s); }}void DeleteBST(BiTree *T,int key){
if(!*T) return; else{
if(key==(*T)->data) Delete(T); else if(key<(*T)->data) DeleteBST(&(*T)->lchird,key); else DeleteBST(&(*T)->rchild,key); }}/*二叉树的中序遍历*/void InorderTraverse(BiTree T){
if(NULL==T) return ; InorderTraverse(T->lchird); printf("%d ",T->data); InorderTraverse(T->rchild);}int main(){
BiTree T=NULL; int array[10]={
62,88,58,47,35,73,51,99,37,93}; printf("二叉排序树的序列为: "); for(int i=0;i<10;i++) InsertBST(&T,array[i]); InorderTraverse(T); printf("\n"); printf("\n"); DeleteBST(&T,99); printf("删除元素99后的二叉排序树的序列为: "); InorderTraverse(T); system("pause"); return 0;}

小结

仔细看这一节,就二叉排序树的删除操作有点细节,它的查找插入和删除操作都是递归实现的,看起来简单,但实际自己写就有点绕。总体来说难度不大,hhh,还是想对自己说:持之以恒

转载地址:http://dstki.baihongyu.com/

你可能感兴趣的文章
动态SQL(Dynamic SQL)
查看>>
在存储过程之间传递数据
查看>>
迁移存储过程
查看>>
GET DIAGNOSTIC 语句
查看>>
Python 简介
查看>>
Python 注释
查看>>
Python 变量
查看>>
Python 数据类型 -- 数字
查看>>
Spring 管理对象
查看>>
Spring 自定义对象初始化及销毁
查看>>
Spring Batch 环境设置
查看>>
字符组转译序列
查看>>
字符转译序列
查看>>
Java 数据类型
查看>>
UTF-16 编码简介
查看>>
Java 变量名
查看>>
Java 四舍五入运算
查看>>
Spring Batch 例子: 运行系统命令
查看>>
Spring Batch 核心概念
查看>>
Spring Batch 例子: 导入定长文件到数据库
查看>>