查找

1.学习总结

1.1查找的思维导图

 

1.2 查找学习体会

查找是对已存入计算机中的数据进行的运算,采用何种查找方法取决于使用哪种数据结构来表示“表”,即表中元素是按何种方式组织的。

在第九章中主要介绍了线性表、数表和哈希表的查找。其中主要要掌握这几种查找方法的ASL的计算以及其查找、插入、删除等主要操作代码的理解。

 

2.PTA实验作业


2.1

题目1:6-2 是否二叉搜索树

设计思路(伪代码或流程图)

bool IsBST(BinTree T)
{
  if (T为空)
    返回 true;
  if (T左孩子为真)
  {
    p指向T的左孩子
    max为T->Data
    循环遍历最大的数据Data
    if(max大于T->Data)
      返回 false;
  }
  if (T右孩子为真)

  {
    p指向T的右孩子
    min为T->Data
    循环遍历最小的数据Data
    if(min小于T->Data)
      返回 false;
  }
  返回 (递归调用函数IsBST()T的左子树以及右子树);
}

代码截图

 

 

PTA提交列表说明。

 

左右孩子与它们父母结点的大小关系判断错误,还有在最后判断大小时不需要考虑等号的情况。


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

设计思路(伪代码或流程图)

int LCA( Tree T, int u, int v )
{
  定义p=T遍历结点
  定义标签m=0
  while(p不为空)
  {
    if(u等于节点数据)
    {
      m=1
      退出循环
     }
    else
    {
      判断u与节点数据的大小关系
      从而决定p指向其左子树或右子树
    }

  }
  if二叉树中没有u
  返回 ERROR;
  初始化p,m
  v的情况同u
  p=T;
  while (p不为空)
  {
    if u和v都小于Key
      则LCA位于左子树中
    else if 如果u和v都大于Key
      则LCA位于右子树中
    else
      找到最近公共祖先
      退出循环
  返回 p->Key
}

代码截图

 

 

PTA提交列表说明。

在二叉树中没有u或v的情况时没有返回ERROR,在最后找到最近公共祖先节点时没有退出循环,导致运行超时,代码错误。

 


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

设计思路(伪代码或流程图)

int main()
{
  输入n
  for(循环n次)
  {
    输入x,y,z
    if(x为"N") 新申请帐户
    {
      if(账号已存在)
      输出ERROR: Exist
      else
      {
        插入账户
        输出"New: OK
      }
    }
    else 老帐户登陆
    {
      if(老帐户QQ号码不存在)
        输出 ERROR: Not Exist
      else
      {
        if(老帐户密码错误)
          puts("ERROR: Wrong PW");
        else 老帐户登陆成功
          输出Login: OK
      }
    }
  }
  return 0
}

代码截图

 

PTA提交列表说明。

 map函数是C++语言,代码中也多次用到C++语句


3.截图本周题目集的PTA最后排名(3分)

本次题目集总分:175分

必做题共:145分

3.1 PTA排名

 

 

3.2 我的总分:115分   

4. 阅读代码(必做,1分)

红黑树

函数说明: 删除某个key
template<typename K ,typename V>
void RBT<K,V>::del(const K& key)
{
  this->root = del(this->root, key);
}
template<typename K, typename V>
Node<K,V>* RBT<K,V>::del(Node<K,V>* node, const K& key)
{
  if (node == NULL)
    return NULL;
  if (!isRed(this->root->lNode) && !isRed(this->root->rNode))
    this->root = RED;
  if (key > node->key)
  {
    if (isRed(node->lNode))
      node = rotateRight(node);
    if (node->rNode != NULL && isRed(node) && !isRed(node->rNode) && !isRed(node->rNode->lNode))
      reverseFlipNode(node);
    node->rNode = del(node->rNode, key);
  }
  else if (key < node->key)
  {
    if (node->lNode != NULL && isRed(node) && !isRed(node->lNode) && !isRed(node->lNode->lNode))
      reverseFlipNode(node);
    if (node->rNode != NULL && isRed(node->rNode) && isRed(node->rNode->lNode))
      node = fixNode(node);
    node->lNode = del(node->lNode, key);
  }
  else
  {
    if (isRed(node))
    {
      if (node->lNode == NULL)
      {
        delete node;
          return NULL;
      }
      else
      {
        node->key = minKey(node->rNode);
        node->val = get(node->key);
        node->rNode = delMin(node->rNode);
      }
    }
    else
    {
      node = rotateRight(node);
      node->rNode = del(node->rNode, key);
    }

  }
  if (isRed(node->rNode) && !isRed(node->lNode))
    node = rotateLeft(node);
  if (isRed(node->lNode) && isRed(node->rNode))
    filpNode(node);

  node->N = size(node->rNode) + size(node->lNode) + 1;
  return node;
}
若 key > node->key,执行删除最大节点的情况保证下层有红色节点,递归右子树
若 key < node->key,执行删除最小节点的情况保证下层有红色节点,递归左子树
若 key = node->key,则:
  当node是红色且左子树为空时,直接删除节点并返回NULL
  当node是红色且左子树不为空且右子树为空时,删除节点并将node赋值成左子树且颜色和左子树相同
  当node是红色且左子树不为空且右子树不为空时,执行reverseFlipNode操作并将右子树最小值min复制到node,同时删除node
  当node是黑色时,这说明node的左子树是红色,所以右旋并递归右子树
如果节点左右子树都是红色,则翻转节点颜色。
如果节点左子树是黑色,右子树是红色,则左旋。

 

posted on 2018-05-27 15:54  HHH,  阅读(248)  评论(1编辑  收藏  举报