查找算法:二分查找、二叉排序树、平衡二叉树(AVL)、红黑树、哈希表

本文介绍了查找算法,包括静态查找表、动态查找表中的二分查找和二叉排序树。详细讨论了二叉排序树的插入、删除操作,以及平衡二叉树AVL树的概念和调整策略。同时,提到了红黑树的特点和插入操作的三种情况,最后概述了哈希表的查找效率和散列函数构造方法。

查找

查找表按照操作方式来分有两大种:静态查找表动态查找表。静态查找表只作查找操作的查找表。动态查找表在查找过程中同时插入查找表中不存在的数据元素, 或者从查找表中删除已经存在的某个数据元素。

顺序表查找(查找O(N)、增删快)

int sequence(int* a,int n,int key){
    int i;
    a[0]=key;//设置哨兵
    i=n;
    while(a[i]!=key)//从尾部开始查找
        i--;
    }
    return i;//返回0表明查找失败
}

有序表查找(查找O(logN)、增删慢)

二分查找前提是关键码有序,顺序存储

思想:取中间记录作为比较对象。若key小于中间值,则在左半区继续查找;否则,在右半区查找。

循环
int Binary_Search(int* a,int n,int key){
    int low=0,high=n-1,mid;//左右都闭
    while(low<=high){
        mid=(low+high)/2;//二分查找
        if(key<a[mid])
            high=mid-1;//key小于中间,左部分查找
        else if(key>a[mid])
            low=mid+1;//key大于中间,在右半区查找
        else{
            return mid;//找到
        }
    }
    return -1;// 没找到
}

递归
int binary_search(int *arr, int left, int right, int key)
{
    assert(arr != NULL);

    if (left <= right)
    {
        int mid = left + ((right - left) >> 1);
        if (key > arr[mid])
        {
            return binary_search(arr, mid+1, right, key);
        }
        else if (key < arr[mid])
        {
            return binary_search(arr, left, mid-1, key);
        }
        else
        {
            return mid;
        }
    }
    else
    {
        return -1;
    }
}

注意:

1. low<=high 最终low和high 会指向同一个数值。 

如果target不一定存在的话,就要用low <= high,最终low大于high导致循环退出,说明target不存在。

如果我们要找的target一定存在的话,那用low < high

2. 如果不mid+1 mid-1 会死循环 严重注意high=mid没关系,但low=mid有可能导致死循环。因为low=high-1时low=mid,如果又进入low=mid分支相当于搜索区间没缩小。但high一定大于mid,所以不会造成死循环。

 

动态查找:二叉排序树(查找和增删速度快)

左子树小于父节点,右子树大于父节点的二叉树就是二叉排序树。对其中序遍历,必为升序。

二叉排序树以链接方式存储,插入删除操作时,不用移动元素,只要找到合适位置,只需修改链接指针即可。

二叉树的二叉链表节点结构

struct BiTNode{
    int data;
    BiTNode* lchild,*rchild;
};//BitNode为结构体

 

// 二叉树节点生成
BiTNode* T,p;//T是结构体指针
// 查找(查找结果给p)
SearchBST(T,93,NULL,&p);//需要对p进行修改,索引用二重指针,指针的指针。
// 插入
InsertBST(&T,50);//需要对T进行修改,索引用二重指针,指针的指针。
// 删除
DeeteBST(&T,50);//需要对T进行修改

查找(递归)

//使用
BiTNode* T,p;//T是结构体指针
SearchBST(T,93,NULL,&p);//需要对p进行修改,索引用二重指针,指针的指针。

Status SearchBST(BiTNode* T,int key,BiTNode* f,BiTNode** p){//T是二叉排序树指针、f指向T的双亲,p为返回查找成功节点,二重指针
    if(T==NULL){//叶节点,没找到
        *p=f;
        return FALSE;
    }
    else if(key==T->data){//查找成功
        *p=T;
        return TRUE;
    }
    else if(key<T->data){//左子树继续查
        return SearchBST(T->lchild,key,T,p);//T->lchild指针
    }
    else{//右子树继续查
        return SearchBST(T->rchild,key,T,p);
    }
}

插入

  • 先调用查找操作将要插入的关键字进行比较
  • 如果在原有的二叉排序树中没有要插入的关键字,则将关键字与查找的结点p(在查找操作中返回的结点)的值进行比较
  • 若p为空,则插入关键字赋值给该节点;
  • 若小于结点p的值,则插入关键字作为结点p的左子树;
  • 若大于结点p的值,则插入关键字作为结点p的右子树;
int InsertBST(BiTNode** T, int key){//这里的T是二重指针,修改时用*T即可。
    
    BiTNode* p,s;//指针
    
    if (!SearchBST( *T, key, NULL, &p)) {  // 没找到key,p返回查找路径上最后一个节点
        
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        
        if (!p)//p为NULL时,第一个节点作为根节点
            *T = 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值