查找
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的左子树是红色,所以右旋并递归右子树
如果节点左右子树都是红色,则翻转节点颜色。
如果节点左子树是黑色,右子树是红色,则左旋。