数据结构和算法(十 五): 查找(顺序表 有序表 二叉排序 AVL )

静态查找和动态查找

查找结构

顺序查找

顺序查找又叫线性查找,是最基本的查找技术,它的查找过程是:从第一个(或者最后一个)记录开始,逐个进行记录的关键字和给定值进行比较,若某个记录的关键字和给定值相等,则查找成功。如果查找了所有的记录仍然找不到与给定值相等的关键字,则查找不成功。

/***************************************
*  数据结构和算法--小甲鱼
*  查找————顺序查找
****************************************/
/*
#include <stdio.h>
//顺序查找,a为要查找的数组,n为要查找的数组的长度
//key为要查找的的关键字
int Sq_search(int *a , int n , int key)
{
    int i;
    for(i = 0; i < n ; i++)
    {
        if(a[i] == key)
        {
            return i;
        }
    }
}
int main()
{
    int search[10] = {1,3,4,5,6,6,9,6,10,1};
    int val = 0;
    val = Sq_search(search , 10 , 6);
    printf("The result is %d\n" ,val );

    return 0;
}

*/

/***************************************
*  数据结构和算法--小甲鱼
*  查找————顺序查找的优化
****************************************/
/*
#include <stdio.h>

//顺序查找的优化
int Sq_search (int *a, int n , int key)
{
    int i = n - 1;
    a[0] = key;
    while(a[i] != key)
    {
        i--;
    }
    return i + 1;
}
int main()
{
    int a[10] = {0,9,9,9,9,9,9,8,5,4};

    int result = 0;

    result = Sq_search(a , 10 , 5);
    printf("%d\n" ,result);
    return 0;
}
*/

/***************************************
*  数据结构和算法--小甲鱼
*  查找————homework01
****************************************/
/*
//有一个信息表,输出1024的信息
#include <stdio.h>
typedef struct student
{
    int id;
    char name[10];
    float score;
}Student;

float Sq_search (Student *stu, int n, int key)
{
    int i;
    for(i = 0 ;i < n ; i++)
    {
        if(stu[i].id == key)
        {
            return stu[i].score;
        }
    }
    return -1;
}
int main()
{
    Student stu[4] = {
         { 1024 , "小甲鱼" , 100},
         { 1025 , "秀" , 60 },
         { 1026 , "天" , 100},
         { 1027 , "啊" , 80 }
    };
    float score = 0;
    score = Sq_search (stu , 4 , 1024);
    printf("the score is %f\n" , score);

    return 0;
}
*/

插值查找(按比例查找)

字典 或者 图书馆

/***************************************
*  数据结构和算法--小甲鱼
*  查找———差值查找(比例查找)
****************************************/
/*
#include <stdio.h>

int bin_search (int str[] , int n, int key )
{
    int low ,high ,mid ;

    low = 0;
    high = n - 1;

    while(low <= high)
    {
        mid = low + (key - str[low])/(str[high] - str[low])*(high - low);//插值查找的唯一不同点
        if(str[mid] == key)
        {
            return mid;
        }
        if(str[mid] < key)
        {
            low = mid + 1;
        }
        if(str[mid] > key)
        {
            high = mid -1;
        }
    }

    return -1;
}
int main()
{

    return 0;
}
*/

斐波那契查找(黄金比例)

/***************************************
*  数据结构和算法--小甲鱼
*  查找----斐波那契查找(黄金比列)
****************************************/
/*
#include <stdio.h>

#define MAXSIZE 20
void fibonacci( int *f)
{ 
    int i;
    
    f[0] = 1;
    f[1] = 1;
    for(i = 2 ;i < MAXSIZE ; i++)
    {
        f[i] = f[i - 2] + f[i - 1];
    }
    
 }
 
int fibonacci_search(int *a , int key ,int n )
{
    int low = 0;
    int high = n - 1;
    int mid = 0;
    
    int F[MAXSIZE]; 
    fibonacci(F);   //生成斐波那契数列
    
     while( n > F[k] - 1)
     {
         ++k;
     }
     
	for( i=n; i < F[k]-1; ++i)
	{
		a[i] = a[high];
	}

	while( low <= high )
	{
		mid = low + F[k-1] - 1;

		if( a[mid] > key )
		{
			high = mid - 1;
			k = k - 1;
		}
		else if( a[mid] < key )
		{
			low = mid + 1;
			k = k - 2;
		}
		else
		{
			if( mid <= high ) 
			{
				return mid;
			}
			else
			{
				return high;
			}
		}
	}
     
    
}
int main()
{
  	int a[MAXSIZE] = {1, 5, 15, 22, 25, 31, 39, 42, 47, 49, 59, 68, 88};
	int key;
	int pos;

	printf("请输入要查找的数字:");
	scanf("%d", &key);
	
	pos = fibonacci_search(a, key, 13);
	
	if( pos != -1 )
	{
		printf("\n查找成功,可喜可贺,可口可乐! 关键字 %d 所在的位置是: %d\n\n", key, pos);
	}
	else
	{
		printf("\nO~No~~小的办事不力,未在数组中找到元素:%d\n\n", key);
	}
		
	return 0;
}

*/

线性索引查找

稠密索引

分块索引

倒排索引

二叉排序树

// 当二叉排序树 T 中不存在关键字等于 key 的数据元素时,
// 插入 key 并返回 TRUE,否则返回 FALSE
Status InsertBST(BiTree *T, int key)
{
    BiTree p, s;
    if( !SearchBST(*T, key, NULL, &p) )
    {
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        
        if( !p )       
        {
            *T = s;     // 插入 s 为新的根结点
        }
        else if( key < p->data )
        {
            p->lchild = s;  // 插入 s 为左孩子
        }
        else
        {
            p->rchild = s;  // 插入 s 为右孩子
        }
        return TRUE;
    }
    else
    {
        return FALSE;   // 树中已有关键字相同的结点,不再插入
    }
}
// 二叉树的二叉链表结点结构定义
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

// 递归查找二叉排序树 T 中是否存在 key
// 指针 f 指向 T 的双亲,其初始值调用值为 NULL
// 若查找成功,则指针 p 指向该数据元素结点,并返回 TRUE
// 否则指针 p 指向查找路径上访问的最后一个结点,并返回 FALSE
Status 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 < T->data )
    {
        return SearchBST( T->lchild, key, T, p );   // 在左子树继续查找
    }
    else
    {
        return SearchBST( T->rchild, key, T, p );   // 在右子树继续查找
    }
}
Status DeleteBST(BiTree *T, int key)
{
    if( !*T )
    {
        return FALSE;
    }
    else
    {
        if( key == (*T)->data )
        {
            return Delete(T);
        }
        else if( key < (*T)->data )
        {
            return DeleteBST(&(*T)->lchild, key);
        }
        else
        {
            return DeleteBST(&(*T)->rchild, key);
        }
    }
}

Status Delete(BiTree *p)
{
    BiTree q, s;
    
    if( (*p)->rchild == NULL )
    {
        q = *p;
        *p = (*p)->lchild;
        free(q);
    }
    else if( (*p)->lchild == NULL )
    {
        q = *p;
        *p = (*p)->rchild;
        free(q);
    }
    else
    {
        q = *p;
        s = (*p)->lchild;
        
        while( s->rchild )
        {
            q = s;
            s = s->rchild;
        }
        
        (*p)->data = s->data;
        
        if( q != *p )
        {
            q->rchild = s->lchild;
        }
        else
        {
            q->lchild = s->lchild;
        }
        
        free(s);
    }
    
    return TRUE;
}

Status DeleteBST(BiTree *T, int key)
{
    if( !*T )
    {
        return FALSE;
    }
    else
    {
        if( key == (*T)->data )
        {
            return Delete(T);
        }
        else if( key < (*T)->data )
        {
            return DeleteBST(&(*T)->lchild, key);
        }
        else
        {
            return DeleteBST(&(*T)->rchild, key);
        }
    }
}

Status Delete(BiTree *p)
{
    BiTree q, s;
    
    if( (*p)->rchild == NULL )
    {
        q = *p;
        *p = (*p)->lchild;
        free(q);
    }
    else if( (*p)->lchild == NULL )
    {
        q = *p;
        *p = (*p)->rchild;
        free(q);
    }
    else
    {
        q = *p;
        s = (*p)->lchild;
        
        while( s->rchild )
        {
            q = s;
            s = s->rchild;
        }
        
        (*p)->data = s->data;
        
        if( q != *p )
        {
            q->rchild = s->lchild;
        }
        else
        {
            q->lchild = s->lchild;
        }
        
        free(s);
    }
    
    return TRUE;
}

平衡二叉树

AVL.c

#define LH 1
#define EH 0
#define RH -1

typedef struct BiTNode
{
	int data;
	int bf;
	struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

void R_Rotate(BiTree *p)
{
	BiTree L;
	L = (*p)->lchild;
	(*p)->lchild = L->rchild;
	L->rchild = (*p);
	*p = L;
	
}

void LeftBalance(BiTree *T)
{
	BiTree L, Lr;
	L = (*T)->lchild;
	
	switch(L->bf)
	{
		case LH:
			(*T)->bf = L->bf = EH;
			R_Rotate(T);
			break;
		case RH:
			Lr = L->rchild;
			switch(Lr->bf)
			{
				case LH:
					(*T)->bf = RH;
					L->bf = EH;
					break
				case EH:
					(*T)->bf = L->bf = EH;
					break;
				case RH:
					(*T)->bf = EH;
					L->bf = LH;
					break;
			}
			Lr->bf = EH;
			L_Rotate(&(*T)->lchild);
			R_Rotate(T);
	}
}

int InsertAVL(BiTree *T, int e, int *taller)
{
	if( !*T )
	{
		*T = (BiTree)malloc(sizeof(BiTNode));
		(*T)->data = e;
		(*T)->lchild = (*T)->rchild = NULL;
		(*T)->bf = EH;
		*taller = TRUE;
	}
	else
	{
		if(e == (*T)->data)
		{
			*taller = FALSE;
			return FALSE;
		}
		if(e < (*T)->data)
		{
			if(!InsertAVL(&(*T)->lchild, e, taller))
			{
				return FALSE;
			}
			if(*taller)
			{
				switch((*T)->bf)
				{
					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(!InsertAVL(&(*T)->rchild, e, taller))
			{
				return FALSE;
			}
			if(*taller)
			{
				switch((*T)->bf)
				{
					case LH:
						(*T)->bf = EH;
						*taller = FALSE;
						break;
					case EH:
						(*T)->bf = RH;
						*taller = TRUE;
						break;
					case RH:
						RightBalance(T);
						*taller = FALSE;
						break;
				}
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41543888/article/details/96591773