线性查找与二叉排序树

本文探讨了线性表查找的顺序和折半查找,重点介绍了分块查找,并深入解析了二叉排序树的查找、插入、生成和删除操作,涵盖了B-树等动态数据结构。通过实例演示了如何在二叉排序树中高效地进行查找、插入和删除操作,适合理解排序和搜索算法的读者。
摘要由CSDN通过智能技术生成

线性表上的查找

  1. 顺序查找
    . 折半查找
    . 分块查找
分块查找
  1. 将表分成若干块
  2. 块间有序,块内无序(或者有序)

树表的查找

  1. 表结构在查找过程中动态生成
  2. 二叉排序树, 平衡二叉树 , B- 树, B+ 树,键树
二叉排序树
  1. 若左子树非空, 则左子树所有结点的值均小于根结点的值
  2. 若右子树非空,则右子树所有结点的值均大于根结点的值
  3. 左右子树本身又是一棵二叉排序树
二叉排序的查找
  1. key > 结点值,查右子树
  2. key > 结点值,查左子树
Tree Search(Tree t , int v){
    //if (t == NULL) return 0;
    if (!t ||t->data == v) return t;
    else if (t->data > v) return Search(t->lchild , v);
    else if (t->data < v) return Search(t->rchild , v);
}
二叉排序的插入
  1. 若二叉排序树为空,则插入结点作为根结点插入到空树中
  2. 否则在左右子树上查找
    1. 树中已经有,不再插入
    2. 没有这个元素
      1. 查找直到某个叶子结点的左子树或者右子树为空为止
      2. 结点为叶子结点的左孩子或者右孩子
void insertTree(Tree *t , int v){
    if (*t == NULL){
        *t = (Tree)malloc(sizeof(TreeNode));
        (*t)->data = v;
        (*t)->lchild = NULL;
        (*t)->rchild = NULL;
        return ;
    }
    if ((*t)->data == v) return ;
    if (v < (*t)->data)insertTree(&((*t)->lchild) , v);
    else if (v > (*t)->data) insertTree(&((*t)->rchild) , v);
   
}
二叉排序的生成
void initTree (Tree *t , int *a , int length){
   int i;
   for (i = 0 ; i < length ; i ++){
       insertTree(t , a[i]);
   }
}
二叉排序的删除
  1. 删除叶子结点,直接删除该结点,其对应双亲的孩子域改为空
  2. 删除的结点只有左子树或者右子树,用左子树或者右子树代替它
  3. 既有左子树又有右子树
    1. 用中序排列的前驱结点代替
    2. 用中序排列的后驱结点来代替
void deleteNode (Tree *t , int v){
    Tree p = *t , pre = NULL , temp = NULL , s = NULL;
    //查找双亲结点以及想要查找的结点
    while (p){
        if (p->data == v) break;
        pre = p;
        if (v < p->data) p = p->lchild;
        else if (v > p->data) p = p->rchild;

    }
    if (!p) return;
    //删除结点
    if (p->lchild == NULL){
        temp = p;
        p = p->rchild;
        //free(temp);
    }
    else if (p->rchild == NULL){
        temp = p;
        p = p->lchild;
        //free(temp);
    }
    else if (p->lchild && p->rchild){
        temp = p;
        s = p->lchild;
        while (s->rchild){
            temp = s;
            s = s->rchild;
        }
        p->data = s->data;
        //将前驱结点的父节点右子树改为前驱结点的左子树
        if (temp != p) temp->rchild = s->lchild;
        else p->lchild = s->lchild;
        free(temp);
        return ;
    }
    
    if (!pre)  *t = pre;
    else if (temp == pre->lchild) pre->lchild = p;
    else  pre->rchild = p;
    free(temp);
}


 == pre->lchild) pre->lchild = p;
    else  pre->rchild = p;
    free(temp);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

觅你风川间!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值