查找

这个作业属于哪个班级 数据结构--网络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 本题知识点

原文地址:https://www.cnblogs.com/YYYchenzeyi/p/14883189.html