• 查找


    这个作业属于哪个班级 数据结构--网络2011/2012
    这个作业的地址 DS博客作业05--查找
    这个作业的目标 学习查找的相关结构
    姓名 陈泽役

    0.PTA得分截图

    1.本周学习总结

    1.1 查找的性能指标

    ASL(Average Search Length),即平均查找长度,在查找运算中,由于所费时间在关键字的比较上,所以把平均需要和待查找值比较的关键字次数称为平均查找长度。
    定义:ASL=∑ni=1pici。
    ASL的计算与移动次数和比较次数有关,决定了该查找算法的时间复杂度。

    1.2 静态查找

    • 顺序查找
      从表的一端开始,逐个扫描,将扫描到的关键字和给定的k值比较,若相等则查找成功,若扫描结束后,未找到关键字的记录,则查找失败。
    int SeqSearch(int *a,int n,int k)
    {
         int i=0;
         while(i<n&&a[i]!=k)
         {
            i++;
         }
         if(i>=n)  //没找到,返回-1
         {
            return -1;
         }
         else
         {
            return i;
         }
    }
    

    时间复杂度:O(n)

    • 二分查找
      设n个元素的数组a已经有序,用low和high两个变量来表示查找的区间,即在a[low]~a[high]中去查找用户输入的值x,和区间中间位置的元素a[mid] (mid=(low+high)/2)作比较,如果相等则找到,算法结束;如果是大于则修改区间(数组为升序数列:low=mid+1;数组为降序数列:high=mid-1);如果是小于也修改区间(数组为升序的改为:high=mid-1,;数组为降序数列:low=mid+1);一直到x=a[mid] (找到该值在数组中的位置)或者是low>high(在数组中找不到x的值)时算法终止;
    int BinSearch(int *a,int n,int k)
    {
         int low=0,high=n-1,mid;
         while(low<=high)
         {
            mid=(mid+high)/2;
            if(a[mid]==k)
            {
                return mid+1;
            }
            if(k<a[mid])
            {
                high=mid-1;
            }
            else
            {
                low=mid+1;
            }
         } 
         return -1;   //没找到
    }
    //递归代码
    int BinSearch(int *a,int low,int high,int k)
    {
       int mid;
       if(low<high)
       {
          mid=(low+high)/2;
          if(a[mid]==k)
             return mid+1;
          if(a[mid]>k)
            BinSearch(a, low,mid-1, k) ;
          else
            BinSearch(a, low,mid+1, k) ; 
       }
       else
          return -1;
    }
    

    时间复杂度:O(logn)

    1.3 二叉搜索树

    二叉排序树要么是空二叉树,要么具有如下特点:

    • 二叉排序树中,如果其根结点有左子树,那么左子树上所有结点的值都小于根结点的值;
    • 二叉排序树中,如果其根结点有右子树,那么右子树上所有结点的值都大小根结点的值;
    • 二叉排序树的左右子树也要求都是二叉排序树;

    1.3.1 如何构建二叉搜索树(操作)

    • 插入

    插入关键字k结点要保证插入后仍然满足BST的性质。

    插入过程为:

    1.若二叉排序树为空,则在给定的一系列关键字序列中,将第一个关键字设为根节点。

    2.若不为空,则与根节点的关键字作比较

    ​ 若比根节点小,作为该根节点的左子树;

    ​ 若比根节点大,作为该根节点的右子树;

    ​ 若相等,则无需插入。

    • 删除

    在删除操作前先用要找到待删除节点的位置

    删除二叉树的结点又有三种情况:

    1.删除叶子节点,可以直接删除,也就是直接让他的双亲结点为空

    2.删除带有一个子节点的节点,则让不为空的子树取代被删结点,也就是让它的双亲结点指向它的不空子树

    3.删除带有两个子节点的结点,可用它的前驱结点(左子树中最大的数,即左子树的最右结点)取代它,或是用它的后继节点(右子树中最小的节点,即右子树中最左的节点)取代它

    1.3.2 如何构建二叉搜索树(代码)

    • 结构体定义
    typedef int KeyType;		//关键字类型
    typedef char* InfoType;	//其他数据类型
    typedef struct node
    {
    	KeyType key;			//关键字域
    	InfoType data;			//其他数据域
            struct node *lchild, *rchild;/*左右孩子*/
    }BSTNode, * BSTree;
    
    • 构建
    void CreateBST(BinTree& BST, int n)/*建树函数*/
    {
    	int x;
    	BST = NULL;//树初始化为空
    	for (int i = 0; i < n; i++)
    	{
    		cin >> x;
    		Insert(BST, x);
    	}
    }
    
    • 插入
    void Insert(BinTree& BST, int X)
    {
    	if (BST == NULL)/*树空*/
    	{
    		BST = new TNode;/*申请*/
    		BST->Data = X;
    		BST->Left = NULL;
    		BST->Right = NULL;
    	}
    	else if (X > BST->Data)/*大于插左边*/
    	{
    		Insert(BST->Left, X);
    	}
    	else if (X < BST->Data)/*小于插右边*/
    	{
    		Insert(BST->Right, X);
    	}
    }
    
    
    • 查找
    BinTree Find(BinTree BST, ElementType X)
    {
        if (BST == NULL)
        {
            return NULL;/*为空返回空*/
        }
        if (X > BST->Data)
        {
            Find(BST->Right, X);/*大于在右*/
        }
        else if (X < BST->Data)
        {
            Find(BST->Left, X);/*小于在左*/
        }
        else
        {
            return BST;/*找到则返回*/
        }
    }
    

    1.4 AVL树

    • AVL树解决什么问题,其特点是什么?
      结合一组数组,介绍AVL树的4种调整做法。
      AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。
      1.LL
      LL情况需要右旋解决,如下图所示:

      2.RR
      RR情况需要左旋解决,如下图所示:

      3.LR
      LR情况需要左右(先B左旋转,后A右旋转)旋解决,如下图所示:

      4.RL
      RL情况需要右左旋解决(先B右旋转,后A左旋转),如下图所示:

    1.5 B-树和B+树

    B-树

    • 定义:是一种多路搜索树(并不是二叉的):

       1.定义任意非叶子结点最多只有M个儿子;且M>2;
      
       2.根结点的儿子数为[2, M];
      
       3.除根结点以外的非叶子结点的儿子数为[M/2, M];
      
       4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
      
       5.非叶子结点的关键字个数=指向儿子的指针个数-1;
      
       6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
      
       7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
      
       8.所有叶子结点位于同一层;
      
    • B-树的特性:
      1.关键字集合分布在整颗树中;

       2.任何一个关键字出现且只出现在一个结点中;
      
       3.搜索有可能在非叶子结点结束;
      
       4.其搜索性能等价于在关键字全集内做一次二分查找;
      
       5.自动层次控制;
      

    B+树

    • 定义:B+树是B-树的变体,也是一种多路搜索树:

       1.其定义基本与B-树同,除了:
      
       2.非叶子结点的子树指针与关键字个数相同;
      
       3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间);
      
       5.为所有叶子结点增加一个链指针;
      
       6.所有关键字都在叶子结点出现;
      
    • B+树的特性:
      1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

       2.不可能在非叶子结点命中;
      
       3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
      
       4.更适合文件索引系统;
      

    1.6 散列查找

    哈希表(又称散列表),是一种存储结构,适用于记录的关键字与存储的地址存在某种关系的数据。设要存储的元素个数为n,再设计长度为m的连续内存单元,通过改变下标改变对应的映射关系,元素存储在内存单元中。
    哈希表的设计:主要是为了解决哈希冲突。在实际应用中,哈希冲突是难以避免的,而它主要与三个因素有关。
    哈希函数的构造方法可采用直接定址法和除留余数法,除留余数法中h(k)=k mod p,p取不大于m的素数时效果最好,减少发生冲突的可能。

    2.PTA题目介绍

    2.1 是否完全二叉搜索树

    2.1.1 伪代码

    2.1.2 提交列表

    2.1.3 本题知识点

    2.2 航空公司VIP客户查询

    2.2.1 伪代码

    2.2.2 提交列表

    2.2.3 本题知识点

    2.3 基于词频的文件相似度

    2.3.1 伪代码

    2.3.2 提交列表

    2.3.3 本题知识点

  • 相关阅读:
    php rewrite 简单
    第十六章 复杂的抽像类结构 简单
    php数学函数 简单
    PHP PCLZIP压缩类的学习笔记 简单
    windows实战Git环境配置msysGit+TortoiseGit 简单
    配置php.ini支持图片exif信息 简单
    使用PHP连接POSTGRES数据库 简单
    jQuery Ajax 实例 全解析 简单
    第十六章 多态性(一) 简单
    C#委托与事件
  • 原文地址:https://www.cnblogs.com/YYYchenzeyi/p/14883189.html
Copyright © 2020-2023  润新知