DS博客作业07--查找

1.思维导图及学习体会

1思维导图

2.谈谈你对查找运算的认识及学习体会

  • 1. 查找的话,好像要求的代码不高,主要是得理解,还有老师讲的STL容器,包括有map和set,有了这两种的确方便多了,不用再慢慢建二叉树还有一些操作比如查找和插入,不过这些老师没太详细讲出来,就只能靠百度,然后看百度的讲解,有些也是难理解,使用容器的确方便多了,不用再自己去建还有一些操作也可以通过函数来解决。
  • 2.虽然这一章对代码要求不高,但是涉及的内容更广更全面了同时也暴露了前面知识的缺漏,比如对树的掌握对递归的掌握还不扎实。而且查找这章除了要求的代码外更多的是关于平衡树的调整操作,B树的删除增加调整操作等,还有关于各种查找方式对应的查找效率ASL的计算是不同的,要搞清楚这些计算首先得先清楚这些查找的原理然后再记忆其ASL的计算方式才不容易混淆。

2.PTA实验作业

2.1.题目1:6-3 二叉搜索树中的最近公共祖先

在一棵树T中两个结点u和v的最近公共祖先(LCA),是树中以u和v为其后代的深度最大的那个结点。现给定某二叉搜索树(BST)中任意两个结点,要求你找出它们的最近公共祖先。

2.1.1设计思路(伪代码)

int find(Tree T, int x)
{
	if  T为空 then  return 0
        end if 
	if  x 等于 关键字 then
		return 1
	else if  x 大于 关键字
		递归函数find(T->Right, x)
	else
		递归函数find(T->Left, x)
        end if 
}

int LCA(Tree T, int u, int v)
{
	if  T 为空 then  返回ERROR
        end if 
	if  find(T, u) 返回0或者find(T, v)返回0  then 	返回ERROR
        end if 
	if T->Key 大于等于u并且T->Key小于v或者 T->Key 小于等于 u并且T->Key 大于等于 v then 
		返回 T->Key
       if (u 大于 T->Key) then      //使用递归找下一个结点 
		递归函数LCA(T->Right, u, v);
	else if u 小于 T->Key   
		递归函数LCA(T->Left, u, v)
   end if
}


2.1.2代码截图

2.1.3本题PTA提交列表说明。

  • Q1:一开始得分是比较低的,是我思路错了,然后写出来的只有空树以及样例对的
  • A1:我以为是想利用指针来知道地址,每个节点存父母的地址,然后写着写着太难了,还刚好打出了跟样例的结果一样,交上去都是错的
  • Q2:老师在课上讲了下如何写了,也就是利用到了二叉搜索树的性质来解决
  • A2:左子树的结点的值都小于根结点的值,右子树的结点的值都大于根结点的值,判断给出的俩个值是不是一个大于一个小于,如果是则这时的根结点就是我们要找的,这样子比本来的我做法容易多了。

2.2.题目1:7-1 QQ帐户的申请与登陆

实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是:据说现在的QQ号码已经有10位数了。


2.2.1设计思路(伪代码)



头文件:
#include <bits/stdc++.h>
#include<iostream>
#include<map>
#include<string>
int main()
    定义整数n,m;
    定义字符串 a,b,c;
    set<string> match;                //初始化set容器match 存账号 
    map<string,string> iter;         //存账号对应的密码 
    输入n;
    while  n大于0且n自减 do
        输入 a、b、c;
        if a等于L then 
            if match.find(b)等于match.end() then               ///调用find函数 已有账号中没找到该账号 
                输出ERROR: Not Exist
            else
                if iter[b]不等于c
                输出ERROR: Wrong PW
                else
                输出Login: OK
                end if 
        else if a等于N 

            if match.find(b)不等于match.end() then 
               输出ERROR: Exist
           else
                输出New: OK
                iter[b]=c;
                match.insert(b);
           end if
       end if
      end while



2.2.2代码截图


2.2.3本题PTA提交列表说明。

  • Q1:刚开始写的时候定义了个数组来打算存放QQ号和密码
  • A1:然后发现交上去发现有个测试点事有关于上下界的问题,然后我就想是不是设置的过小了,修改了数组大小再交上去过了那个测试点,还有字符数组末尾为\0得记住
  • Q2:后面就不会再改了,看了其他人代码,才知道要用容器更快,用了map容器处理账号密码的时候,就可以更快配对。
  • A2:在查找可以用find()函数,返回的是一个迭代器,若该下标不存在,返还end()。查找还能通过直接访问下标,类似数组的形式,但是若不存在,会插入数据,会直接插入。

2.3.题目1:6-1 二叉搜索树的操作集

本题要求实现给定二叉搜索树的5种常用操作。

2.3.1设计思路(伪代码)


Position FindMin(BinTree BST)

    if BST 不为空 then 
        if  BST的左孩子不空 then 
            递归调用函数 FindMin(BST->Left);
        
        else 
            返回BST; 
    end if 
    


Position FindMax(BinTree BST)

    if  BST 不为空  then
        if BST右孩子不为空 then 
            while BST右孩子不为空
                BST = BST->Right;
            end while          
        end if 
    end if 
        返回 BST;
    


BinTree Insert(BinTree BST, ElementType X)

    if  BST为空 then  
        定义BinTre类型结点p;
        申请动态空间;
        X存入p的数据域;
        p的左右孩子初始化为空; 
        BST = p;
    else if X < BST->Data then
        BST->Left = Insert(BST->Left, X);
    else if X < BST->Data then
        BST->Right = Insert(BST->Right, X); //利用递归来进行数据的插入 
    end if
    返回 BST;

BinTree Delete(BinTree BST, ElementType X)

    if BST 为空 then
        输出Not Found
    else 
        if  X < BST->Data then
            BST->Left = Delete(BST->Left, X);
        else if  X > BST->Data then 
            BST->Right = Delete(BST->Right, X);
        else if X = BST->Data
            if  BST的左右孩子都不为空 then
                新建BinTree类型结点p;
                p = FindMin(BST->Right);
                BST->Data = p->Data;
                BST->Right = Delete(BST->Right, BST->Data);
            
            else 
                if BST的左孩子为空 then 
        BST = BST->Right;
                else if BST右孩子为空 then 
        BST = BST->Left;
            end if 
        end if
    end if
    返回 BST


Position Find(BinTree BST, ElementType X)

    if  BST为空 then  
        返回空值; 
    if BST->Data == X then
        返回BST结点;
    else if X < BST->Data then 
        利用递归找下一个左孩子结点; 
    else if (X > BST->Data)
        利用递归找下一个左孩子结点; 
    返回BST

2.3.2代码截图


2.3.3本题PTA提交列表说明。

  • Q1:除了删除函数那一部分难写外,其他函数都还可以,就是找最大值和找最小值的函数中有错误,在提交代码后发现找最大值的函数FindMax出现错误
  • A1:本来我也是写成递归形式来在右子树中找最右下角的那个数即为最大值,然后交上去就是错的,后来才改写成while语句,当时没判断后已经到空了仍进行操作吧
  • Q2:删除函数是真的不好写,思路知道,可是代码上不好写,还是乖乖去百度了下,麻烦的地方就在于要上删除的结点有左孩子也有右孩子
  • A2:在删除这个结点同时,还要从他的右孩子中找一个最大的来放到删除的这个位置,本来我还以为要调用的是FINDMAX函数,然后就是这里出错了,应该再调用删除函数

3阅读代码

3.1 题目:二叉搜索树的结构


二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。(摘自百度百科)

给定一系列互不相等的整数,将它们顺次插入一棵初始为空的二叉搜索树,然后对结果树的结构进行描述。你需要能判断给定的描述是否正确。例如将{ 2 4 1 3 0 }插入后,得到一棵二叉搜索树,则陈述句如“2是树的根”、“1和4是兄弟结点”、“3和0在同一层上”(指自顶向下的深度相同)、“2是4的双亲结点”、“3是4的左孩子”都是正确的;而“4是2的左孩子”、“1和3是兄弟结点”都是不正确的。

3.2 解题思路

首先建树,读查询的字符串输入是个问题,如何去把每条查询的节点编号提取出来是解决的关键
不要每一条查询都去遍历树,可以先把节点之间的关系:是否在同一层、左孩子、右孩子、祖先节点等保存在map中后边直接根据map判断
还要就是可能查询的节点编号不在树上


3.3 代码截图





3.4 学习体会


自己来写肯定写不出来,如果是我来写的话建树过程中记录每个点高度,以及每个点指向的结点,这样子在后面查询的时候会方便点。对map函数的应用就没怎么太大的理解 ,这个作者对于map容器理解的很好,我不会像用数组一样利用下标来操作,不过这样也更体现map的快速查找功能。之前百度讲解map容器时候有说过可以使用下标,但是如果map下标运算符[]运用不得当,也会造成意想不到的问题。


posted @ 2019-06-16 17:28  ZWL.。。。  阅读(232)  评论(0编辑  收藏  举报