数据结构C语言版清华大学严蔚敏(学习笔记总结6)——查找全代码:二分查找、折半查找、分块查找、哈希查找、哈希表、平衡二叉树【另附学习笔记】

 https://blog.csdn.net/weixin_51538341/article/details/122266004?spm=1001.2014.3001.5501

 一. 二分查找(折半查找)


核心思想:将nn个元素分成个数大致相同的两半,取a[n/2]a[n/2]与欲查找的xx作比较,如果x=a[n/2]x=a[n/2]则找到xx,算法终止。如果x<a[n/2]x<a[n/2],则我们只要在数组aa的左半部继续搜索xx(这里假设数组元素呈升序排列)。如果x>a[n/2]x>a[n/2],则我们只要在数组a的右 半部继续搜索x.其算法时间复杂度O(lgn)
 

//c/c++
int binary_find(int *num,int length,int m){
    int sta=0,end = length-1;
    int mid;
    while(sta <= end){
        mid =(sta+end)/2;
        if (m > num[mid])sta = mid+1;
        else{
            if (m < num[mid])end = mid-1;
            else return mid;
        }       
    }
    return -1;
}

二. 分块查找

// c/c++
struct  block{
    int     key;
    int     start;
    int     end;
}blk[3];

int block_find(int *num,int k){
    for(int i=0;i<3;i++){
        if(k<=blk[i].key){
            int j=blk[i].start;
            while(j<=blk[i].end){
                if(k!=num[j])j++;
                else return j;\
            }
        }
    }
    return(-1);
}

 三. 哈希查找

// c/c++
int key(int num){
    return(num%MAX);
}

void    create_hash_key(int *hash_table,int num){
    int t,pos;
    t = key(num);
    pos =t;
    while(hash_table[t]!=-1 ){
        t = (t+1)%MAX;
        if(pos == t){
            printf("the hashtable has been full!\n");
            return;
        }
    }
    hash_table[t] = num;
}

int hash_find(int *hash_table,int num){
    int t,pos;
    t = key(num);
    pos = t;
    while(hash_table[t] != -1 && hash_table[t] != num){
        t = (t+1)%MAX;
        if(pos == t){
            printf("not found\n");
            return(-1);
        }
    }
    if(hash_table[t] == -1){
        printf("not found\n");
        return(-1);
    }
    else    return(t);
}

四、平衡二叉树 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{
    int data;
    int bf;
    struct BiTNode* lchild, *rchild;
}BiTNode, *BiTree;
typedef enum{false,true}bool;
//左旋转
void L_Rotate(BiTree *T)
{
    BiTree R = (*T)->rchild;
    (*T)->rchild = R->lchild;
    R->lchild = *T;
    *T = R;
    return;
}
//右旋转
void R_Rotate(BiTree *T)
{
    BiTree L = (*T)->lchild;
    (*T)->lchild = L->rchild;
    L->rchild = *T;
    *T = L;
    return;
}
#define LH +1
#define EH 0
#define RH -1
//T 的左边高,不平衡,使其平衡,右旋转,右旋转前先检查L->bf,
//如果为RH,L要先进行左旋转,使T->lchild->bf和T->bf一致
void LeftBalance(BiTree* T)
{
    BiTree L,Lr;
    L = (*T)->lchild;
    Lr = L->rchild;
    switch (L->bf)
    {
        case LH:
            L->bf = (*T)->bf =  EH;
            R_Rotate(T);
            break;
        case RH:
            switch (Lr->bf)
            {
                case LH:
                    L->bf = EH;
                    (*T)->bf = RH;
                    break;
                case EH:
                    L->bf = (*T)->bf = EH;
                    break;
                case RH:
                    L->bf = LH;
                    (*T)->bf = EH;
                    break;
            }
            Lr->bf = EH;
            L_Rotate(&L);
            R_Rotate(T);
            break;
    }
}
//T 的右边高,不平衡,使其平衡,左旋转,左旋转前先检查R->bf,
//如果为LH,R要先进行右旋转,使T->rchild->bf和T->bf一致
void RightBalance(BiTree* T)
{
    BiTree R,Rl;
    R = (*T)->rchild;
    Rl = R->lchild;
    switch(R->bf)
    {
        case RH:
            R->bf = (*T)->bf = EH;
            L_Rotate(T);
            break;
        case LH:
            switch(R->bf)
            {
                case LH:
                    R->bf = RH;
                    (*T)->bf = EH;
                    break;
                case EH:
                    R->bf = (*T)->bf = EH;
                    break;
                case RH:
                    R->bf = EH;
                    (*T)->bf = LH;
                    break;
            }
            Rl->bf = EH;
            R_Rotate(&R);
            L_Rotate(T);
            break;
    }
}
//往平衡二叉树上插入结点
bool InsertAVL(BiTree* T,int data,bool *taller)
{
    if(*T == NULL)  //找到插入位置
    {
        *T = (BiTree)malloc(sizeof(BiTNode));   
        (*T)->bf = EH;
        (*T)->rchild = (*T)->lchild = NULL;
        (*T)->data = data; 
        *taller = true;
    }
    else
    {
        if(data == (*T)->data)  //树中有相同的结点数据直接返回
        {
            *taller = false;
            return false;
        }
        if(data < (*T)->data)   //往左子树搜索进行插入
        {
            if(!InsertAVL(&(*T)->lchild,data,taller))   //树中有相同的结点
            {
                *taller = false;
                return false;
            }   
            if (*taller)
            {
                switch ((*T)->bf)               //T插入结点后,检测平衡因子,根据情况,做相应的修改和旋转
                {
                case LH:
                    LeftBalance(T);             //插入后左边不平衡了,让其左平衡
                    *taller = false;
                    break;
                case EH:
                    (*T)->bf = LH;
                    *taller = true;
                    break;
                case RH:
                    (*T)->bf = EH;
                    *taller = false;
                    break;
                }
            }
        }
        else                    //往右子树搜索进行插入
        {
            if(!Insert(&(*T)->rchild),data,taller)      //树中有相同的结点
            {
                *taller = false;
                return false;
            }
            if (*taller)        //插入到右子树中且长高了
            {
                switch ((*T)->bf)                       //T插入结点后,检测平衡因子,根据情况,做相应的修改和旋转
                {
                case LH:
                    (*T)->bf = EH;
                    *taller = false;
                    break;
                case EH:
                    (*T)->bf = RH;
                    *taller = true;
                    break;
                case RH:
                    R_Balance(T);                       //插入后右边不平衡了,让其右平衡
                    *taller = false;
                    break;
                }
            }
        }
    }
    return true;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1.1 数组和字符串 2 1.1.1 一维数组的倒置 2 范例1-1 一维数组的倒置 2 ∷相关函数:fun函数 1.1.2 一维数组应用 3 范例1-2 一维数组应用 3 1.1.3 一维数组的高级应用 5 范例1-3 一维数组的高级应用 5 1.1.4 显示杨辉三角 7 范例1-4 显示杨辉三角 7 ∷相关函数:c函数 8 1.1.5 魔方阵 9 范例1-5 魔方阵 9 1.1.6 三维数组的示 14 范例1-6 三维数组的示 14 ∷相关函数:InitArray函数 1.1.7 多项式的数组示 17 范例1-7 多项式数组的示 17 1.1.8 查找矩阵的马鞍点 19 范例1-8 查找矩阵的马鞍点 19 ∷相关函数:Get_Saddle函数 1.1.9 对角矩阵建立 21 范例1-9 对角矩阵建立 21 ∷相关函数:Store函数 1.1.10 三对角矩阵的建立 22 范例1-10 三对角矩阵的建立 22 ∷相关函数:Store函数 1.1.11 三角矩阵建立 24 范例1-11 三角矩阵建立 24 ∷相关函数:Store函数 1.1.12 对称矩阵的建立 25 范例1-12 对称矩阵的建立 25 ∷相关函数:store函数 1.1.13 字符串长度的计算 28 范例1-13 字符串长度的计算 28 ∷相关函数:strlen函数 1.1.14 字符串的复制 29 范例1-14 字符串的复制 29 ∷相关函数:strcpy函数 1.1.15 字符串的替换 31 范例1-15 字符串的替换 31 ∷相关函数:strrep函数 1.1.16 字符串的删除 33 范例1-16 字符串的删除 33 ∷相关函数:strdel函数 1.1.17 字符串的比较 35 范例1-17 字符串的比较 35 ∷相关函数:strcmp函数 1.1.18 字符串的抽取 36 范例1-18 字符串的抽取 36 ∷相关函数:substr函数 1.1.19 字符串的分割 38 范例1-19 字符串的分割 38 ∷相关函数:partition函数 1.1.20 字符串的插入 40 范例1-20 字符串的插入 40 ∷相关函数:insert函数 1.1.21 字符串的匹配 42 范例1-21 字符串的匹配 42 ∷相关函数:nfind函数 1.1.22 字符串的合并 43 范例1-22 字符串的合并 43 ∷相关函数:catstr函数 1.1.23 文本编辑 45 范例1-23 文本编辑 45 ∷相关函数:StrAssign函数 1.2 栈和队列 54 1.2.1 用数组仿真堆栈 54 范例1-24 用数组仿真堆栈 54 ∷相关函数:push函数 pop函数 1.2.2 用链仿真堆栈 57 范例1-25 用链仿真堆栈 57 ∷相关函数:push函数 pop函数 1.2.3 顺序栈公用 59 范例1-26 顺序栈公用 59 ∷相关函数:push函数 pop函数 1.2.4 进制转换问题 61 范例1-27 进制转换问题 61 ∷相关函数:MultiBaseOutput函数 1.2.5 顺序队列操作 64 范例1-28 顺序队列操作 64 ∷相关函数:push函数 pop函数 1.2.6 循环队列 66 范例1-29 循环队列 66 ∷相关函数:EnQueue函数 DeQueue函数 1.2.7 链队列的入队、出队 69 范例1-30 链队列入队、出队 69 ∷相关函数:push函数 pop函数 1.2.8 舞伴问题 71 范例1-31 舞伴问题 71 ∷相关函数:EnQueue函数 DeQueue函数 DancePartner函数 1.3 链 75 1.3.1 头插法建立单链 75 范例1-32 头插法建立单链 75 ∷相关函数:createlist函数 1.3.2 限制链长度建立单链 77 范例1-33 限制链长度建立长单链 77 ∷相关函数:createlist函数 1.3.3 尾插法建立单链 79 范例1-34 尾插法建立单链 79 ∷相关函数:createlist函数 1.3.4 按序号查找单链 80 范例1-35 按序号查找单链 80 ∷相关函数:getnode函数 1.3.5 按值查找单链 82 范例1-36 按值查找单链 82 ∷相关函数:locatenode函数 1.3.6 链的插入 84 范例1-37 链的插入 84 ∷相关函数:insertnode函数 1.3.7 链的删除 86 范例1-38 链的删除 86 ∷相关函数:deletelist函数 1.3.8 归并两个单链 88 范例1-39 归并两个单链 88 ∷相关函数:concatenate函数 1.3.9 动态堆栈 90 范例1-40

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

玛卡巴卡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值