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;
}