• Chapter 8(查找)



    1.二分查找和插值查找
    //************************Search.h***********************************
    #ifndef SEARCH_H
    #define SEARCH_H
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int BiSearch(int array[],int n,int key);
    
    int IVSearch(int array[],int n,int key);
    
    int FibSearch(int array[],int n,int key);
    
    
    
    #endif //SEARCH_H
    
    
    //************************Search.c*************************************
    #include "Search.h"
    
    
    //折半查找
    int BiSearch(int array[],int n,int key)
    {
    	if(NULL == array)return -1;
    	int left = 0;
    	int right= n-1;
    	int mid  = (left+right)/2;
    
    	while(left <= right)
    	{
    		if(array[mid] == key)
    		{
    			return mid;
    		}
    		else if(array[mid] > key)
    		{
    			right = mid-1;
    		}
    		else if(array[mid] < key)
    		{
    			left = mid+1;
    		}
    		mid = (left+right)/2;
    	}
    	return -1;
    }
    
    
    //插值查找
    int IVSearch(int array[],int n,int key)
    {
    	if(NULL == array)return -1;
    	int left = 0;
    	int right= n-1;
    	int mid  = left+(right-left)*(key-array[left])/(array[right]-array[left]);
    
    	while(left <= right)
    	{
    		if(array[mid] == key)
    		{
    			return mid;
    		}
    		else if(array[mid] > key)
    		{
    			right = mid-1;
    		}
    		else if(array[mid] < key)
    		{
    			left = mid+1;
    		}
    		mid  = left+(right-left)*(key-array[left])/(array[right]-array[left]);
    	}
    	return -1;
    }
    
    
    
    int FibSearch(int array[],int n,int key)
    {
    	int F[] = {1,1,2,3,5,8,13,21,34,55,89};
    	
    
    	int left = 0;
    	int right= n-1;
    	int mid;
    
    	int k = 0;
    	while(n>F[k]-1)
    	{
    		k++;
    	}
    	for(int i=n;i < F[k])
    
    }
    
    
    //************************SearchTest.c*************************************
    #include "Search.h"
    
    
    int main()
    {
    	int a[10] = {1,16,24,35,47,59,62,73,88,99};
    	int key = 62;
    
    	printf("position: %d 
    ",BiSearch(a,10,key));
    	printf("position: %d 
    ",IVSearch(a,10,key));
    }


    2.斐波那契查找
    #include <stdio.h>  
    #include <stdlib.h>  
    #define MAXN 20  
      
    /* 
     *产生斐波那契数列 
     * */  
    void Fibonacci(int *f)  
    {  
        int i;  
        f[0] = 1;  
        f[1] = 1;  
        for(i = 2;i < MAXN; ++i)  
            f[i] = f[i - 2] + f[i - 1];  
    }  
      
    /* 
     * 查找 
     * */  
    int Fibonacci_Search(int *a, int key, int n)  
    {  
        int i, low = 0, high = n - 1;  
        int mid = 0;  
        int k = 0;  
        int F[MAXN];  
        Fibonacci(F);  
        while(n > F[k] - 1)          //计算出n在斐波那契中的数列  
            ++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 -1;  
            }  
        }  
        return 0;  
    }  
      
    int main()  
    {     
        int a[MAXN] = {5,15,19,20,25,31,38,41,45,49,52,55,57};  
        int k, res = 0;  
        printf("请输入要查找的数字:
    ");  
        scanf("%d", &k);  
        res = Fibonacci_Search(a,k,13);  
        if(res != -1)  
            printf("在数组的第%d个位置找到元素:%d
    ", res + 1, k);  
        else  
            printf("未在数组中找到元素:%d
    ",k);  
        return 0;  
    }  
    


    3.二叉排序树
    //****************************BiSortTree.h*************************
    #ifndef BISORTTREE_H
    #define BISORTTREE_H
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    typedef int datatype;
    
    typedef struct BiSNode
    {
    	datatype data;
    	struct BiSNode *left,*right;
    }BiSNode,*BiSTree;
    
    
    //在二叉排序树中查找key
    bool SearchBST(BiSTree T,datatype key,BiSTree f,BiSTree *p);
    
    //按顺插入
    bool InsertBST(BiSTree *T,datatype key);
    
    //删除节点
    bool DeleteBST(BiSTree *T,datatype key);
    
    
    bool Delete(BiSTree *p);
    
    
    #endif  //BISORTTREE_H
    
    
    //****************************BiSortTree.c*************************
    #include "BiSortTree.h"
    
    //在二叉排序树中查找key
    bool SearchBST(BiSTree T,datatype key,BiSTree f,BiSTree *p)
    {
    	if(!T)
    	{
    		*p = f;
    		return false;
    	}
    	else if(key == T->data)
    	{
    		*p = T;
    		return true;
    	}
    	else if(key < T->data)
    	{
    		return SearchBST(T->left,key,T,p);
    	}
    	else
    	{
    		return SearchBST(T->right,key,T,p);
    	}
    }
    
    //按顺插入
    bool InsertBST(BiSTree *T,datatype key)
    {
    	BiSTree p,s;
    	if(!SearchBST(*T,key,NULL,&p))
    	{
    		s = (BiSTree)malloc(sizeof(BiSNode));
    		s->data = key;
    		s->left = s->right = NULL;
    
    		if(!p)
    		{
    			*T = s;
    		}
    		else if(key < p->data)
    		{
    			p->left = s;
    		}
    		else 
    		{
    			p->right = s;
    		}
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    
    //删除节点
    bool DeleteBST(BiSTree *T,datatype key)
    {
    	if(!*T)
    	{
    		return false;
    	}
    	else
    	{
    		if(key == (*T)->data)
    		{
    			return Delete(T);
    		}
    		else if(key < (*T)->data)
    		{
    			DeleteBST(&(*T)->left,key);
    		}
    		else
    		{
    			DeleteBST(&(*T)->right,key);
    		}
    	}
    }
    
    bool Delete(BiSTree *p)
    {
    	BiSTree q,s;
    
    	if(NULL == (*p)->left)
    	{
    		q = *p;
    		*p = (*p)->right;
    		free(q);
    	}
    	else if(NULL == (*p)->right)
    	{
    		q = *p;
    		*p = (*p)->left;
    		free(q);
    	}
    	else
    	{
    		q = *p;
    		s = (*p)->left;
    
    		while(s->right)
    		{
    			q = s;
    			s = s->right;
    		}
    		(*p)->data = s->data;
    
    		if(q != *p)
    		{
    			q->right = s->left;
    		}
    		else
    		{
    			q->left  = s->left;
    		}
    		free(s);
    	}
    	return true;
    }
    
    //****************************BiSortTreeTest.c*************************
    #include "BiSortTree.h"
    
    
    
    int main()
    {
    	int i;
    	int a[10] ={62,88,58,47,35,73,51,99,37,93};
    	BiSTree T = NULL;
    	for(i = 0;i < 10;i++)
    	{
    		InsertBST(&T,a[i]);
    	}
    	
    	BiSTree p,f;
    	printf("%d 
    ",p->data);
    	SearchBST(T,58,f,&p);
    	printf("%d 
    ",p->data);
    
    	DeleteBST(&T,58);
    
    	printf("%d 
    ",p->data);
    }

    4.AVL(平衡二叉树)
    #include<stdio.h>
    #include<stdlib.h>
    #include<stdbool.h>
    #define EH 0            /*等高*/
    #define LH 1            /*左高*/
    #define RH -1            /*右高*/
        
    typedef int ElemType;                 /*数据类型*/
    
    typedef struct BiTree{
        ElemType data;                    /*数据元素*/
        int BF;                         /*平衡因子*/
        struct BiTree *lchild,*rchild;     /*左右子女指针*/
    }*Bitree,BitreeNode;
    
    
    int InsertAVL(Bitree *T,ElemType e,bool *taller);
    void LeftBalance(Bitree *T);
    void RightBalance(Bitree *T);
    void R_Rotate(Bitree *T);
    void L_Rotate(Bitree *T);
    bool *taller;
    //bool *taller= (bool *)malloc(sizeof(bool));
    
    int main(void)
    {
        taller= (bool *)malloc(sizeof(bool));
        int data;
        Bitree T=NULL;
        while(1)
        {
            printf("enter the number(zero to exit):");
            scanf("%d",&data);
            if(0==data)break;
            InsertAVL(&T,data,taller);
            
        }
        
        
        
        return 0;
    }
    
    
    /*若在平衡的二叉排序树T 中不存在和e 有相同关键码的结点,则插入一个数据元素为e 的*/
    /*新结点,并反回1,否则反回0。若因插入而使二叉排序树失去平衡,则作平衡旋转处理,*/        
    /*布尔型变量taller 反映T 长高与否*/    
    int InsertAVL(Bitree *T,ElemType e,bool *taller)
    {
        if(!*T)                /*插入新结点,树“长高”,置taller 为TURE*/
        {
            (*T)=(Bitree)malloc(sizeof(BitreeNode));
            (*T)->data = e;
            (*T)->lchild = (*T)->rchild = NULL;
            (*T)->BF = EH;
            *taller = true;
        }
        else
        {
            if(e==(*T)->data)        /*树中存在和e 有相同关键码的结点,不插入*/
            {
                *taller = false;
                return 0;
            }    
            if(e<(*T)->data)
            {
                if(!InsertAVL(&(*T)->lchild,e,taller))    return 0;  /*未插入*/
                if(*taller)
                switch((*T)->BF)
                {    
                    case EH :                    /*原本左、右子树等高,因左子树增高使树增高*/
                        (*T)->BF=LH;
                        *taller=true;
                        break;
                    
                    case LH :                    /*原本左子树高,需作左平衡处理*/
                        LeftBalance(T);
                        *taller=false;
                        break;
                    
                    case RH :                    /*原本右子树高,使左、右子树等高*/
                        (*T)->BF=EH; 
                        *taller=false;
                        break;
                        
                }
                
            }
            else
            {
                if(!InsertAVL(&(*T)->rchild,e,taller))    return 0;  /*未插入*/
                if(*taller)
                switch((*T)->BF)
                {    
                    case EH :                    /*原本左、右子树等高,因右子树增高使树增高*/
                        (*T)->BF=RH;
                        *taller=true;
                        break;
                    
                    case LH :                    /*原本左子树高,使左、右子树等高*/
                        (*T)->BF=EH; 
                         *taller=false;
                         break;
                    
                    case RH :                    /*原本右子树高,需作右平衡处理*/
                        RightBalance(T);
                        *taller=false;
                         break;
                        
                }
            }
        }
        return 1;
    }
    
    
    
    /*对以*p 指向的结点为根的子树,作左平衡旋转处理,处理之后,*p 指向的结点为子树的新根*/
    void LeftBalance(Bitree *T)
    {
        Bitree L=(*T)->lchild,Lr;             /*L 指向*T左子树根结点*/
        switch(L->BF)                /*检查L 平衡度,并作相应处理*/
        {
            case LH:                    /*新结点插在*p 左子树的左子树上,需作单右旋转处理*/
                (*T)->BF=L->BF=EH;
                 R_Rotate(T);
                 break;
            case EH:             /*原本左、右子树等高,因左子树增高使树增高*/
                (*T)->BF=LH;    //这里的EH好像没有写的必要 
                  *taller=true;
                  break;
            case RH:                     /*新结点插在*T 左孩子的右子树上,需作先左后右双旋处理*/
                Lr=L->rchild;             /*Lr 指向*p 左孩子的右子树根结点*/    
                switch(Lr->BF)         /*修正*T 及其左子树的平衡因子*/
                {
                    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(&L);        /*对*T 的左子树作左旋转处理*/
                R_Rotate(T);        /*对*T 作右旋转处理*/
        }
    }
    //这里和leftbalance一个道理,试着自己写一下 
    void RightBalance(Bitree *T)
    {
        Bitree Lr= (*T)->rchild,L;
        switch(Lr->BF)
        {
            case EH:
                *taller = true;
                (*T)->BF = RH;
                break;
            case RH:
                (*T)->BF=Lr->BF=EH;
                L_Rotate(T);
                break;
            case LH:
                L = Lr->lchild;
                switch(L->BF)
                {
                    case EH:
                        (*T)->BF=Lr->BF= EH;
                        break;
                    case RH:
                        Lr->BF= EH;
                        (*T)->BF = LH;
                        break;
                    case LH:
                        (*T)->BF = LH;
                        Lr->BF = EH;
                        break;
                    
                }
                L->BF = EH;
                R_Rotate(&Lr);        
                L_Rotate(T);    
            
        }
    }
    
    
    /*对以*T 指向的结点为根的子树,作右单旋转处理,处理之后,*T 指向的结点为子树的新根*/
    void R_Rotate(Bitree *T)
    { 
        Bitree L=(*T)->lchild;                 /*L 指向*T 左子树根结点*/
        (*T)->lchild=L->rchild;                 /*L 的右子树挂接*T 的左子树*/
        L->rchild=*T; *T=L;             /* *L 指向新的根结点*/
    }
    
    
    /*对以*p 指向的结点为根的子树,作左单旋转处理,处理之后,*p 指向的结点为子树的新根*/
    void L_Rotate(Bitree *T)
    { 
        Bitree Lr=(*T)->rchild;                 /*Lr 指向*T 右子树根结点*/
        (*T)->rchild=Lr->lchild;                 /*L 的左子树挂接*p 的右子树*/
        Lr->lchild=*T; 
        *T=Lr;                                     /* *L 指向新的根结点*/
    }

    附件列表

  • 相关阅读:
    iOS面试题总结整理(附答案)
    iOS App上传项目遇到的问题
    Could not find Developer Disk Image
    xcode下载方式
    iOS App上架流程(2016详细版)
    Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得
    iOS开发之17个常用代码整理
    iOS求职之OC面试题
    Android xmpp 连接基本方法
    Ubuntu安装过程
  • 原文地址:https://www.cnblogs.com/LyndonMario/p/9326364.html
Copyright © 2020-2023  润新知