题目
实验目的
学会基本的查找算法,掌握二分查找、二分排序树等,学会将哈希表应用于快速查找、统计等。
typedef struct BiTNode {
ElemType data;
struct BiTNode* lchild, * rchild;
} BiTNode, * BiTree;
实验内容:
-
实现二叉排序树(课上完成)
//在T上搜索key。查找成功则返回相应节点,否则返回NULL; BiTNode* SearchBST(BiTree T, ElemType key) //在T 上插入key。成功插入,则返回所插入节点;否则返回NULL。 BiTNode* InsertBst(BiTree T, ElemType key) //CreateBst(BiTree &T);//根据控制台输入或者数组、字符串等你希望的方式来创建BST //在T上删除key。成功删除则返回所要删除的节点,否则返回NULL。注意:删除实际上只是将相应节点从树上分离出来。 BiTNode* DeleteBst(BiTree T, ElemType key)
提示:
- 可基于"BST-基础代码.txt"实现。
- 很多实现均可基于递归。
参考: - 二叉搜索树(OJ):http://jmunetds.openjudge.cn/ex5/901/
- 二叉搜索树的节点删除(OJ):http://jmunetds.openjudge.cn/ex5/902/
-
PTA函数题[必做]
- 6-1:“是否二叉搜索树”(利用BST的递归定义)
- 6-2:“二叉搜索树中的最近公共祖先”(利用BST的递归定义、利用BST左小右大或左大右小的特性)
-
PTA编程题[必做]:
- 7-1:*QQ帐户的申请与登陆(哈希,map)。
- 参考资料:C++使用: C++中map的基本操作和用法
- 7-2:航空公司VIP客户查询(哈希链)
- 7-1:*QQ帐户的申请与登陆(哈希,map)。
提交要求:
- 对于要求课上完成的题目,请在实验课结束前提交代码至课堂派,并在课后完成实验报告;
- 对于不要求课上完成的题目,请在实验课结束后提交代码至课堂派;
- PTA上的题目,还需要提交测试通过;
- 在实验报告中对每一道题都需要描述算法思路(可以用伪代码也可以用文字,还可以用ppt演示算法流程),实验报告为一个word、ppt或pdf文档,每个同学提交时将所有代码和实验报告统一放在文件夹中,文件夹命名为“学号后四位_姓名”,然后提交压缩文件,如有不同版本,请用“学号后四位_姓名_版本号”标识。
实验报告
二叉树节点搜索
BiTNode* SearchBST(BiTree T, ElemType key)
//在T上搜索key。查找成功则返回相应节点,否则返回NULL;
二叉树节点插入
BiTNode* InsertBst(BiTree T, ElemType key)
//在T上插入key。成功插入,则返回所插入节点;否则返回NULL。
二叉树创建
CreateBst(BiTree &T);
//根据控制台输入或者数组、字符串等你希望的方式来创建BST
二叉树节点删除
BiTNode* DeleteBst(BiTree T, ElemType key)
//在T上删除key。成功删除则返回所要删除的节点,否则返回NULL。注意:删除实际上只是将相应节点从树上分离出来。
总成果展示
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode* lchild, * rchild;
} BiTNode, * BiTree;
BiTNode* CreateNode(int v)
{
BiTNode* node = new BiTNode;
node->data = v;
node->lchild = NULL;
node->rchild = NULL;
return node;
}
//在T上搜索key。查找成功则返回相应节点,否则返回NULL;
BiTNode* SearchBST(BiTree T, ElemType key)
{
while (T)
{
if (T->data == key)
{
printf("Find %d !\n", key);
return T;
}
else if (T->data > key)
T = T->lchild;
else
T = T->rchild;
}
printf("Can not find %d !\n", key);
return NULL;
}
//在T上插入key。成功插入,则返回所插入节点;否则返回NULL。
BiTNode* InsertBST(BiTree& T, ElemType key)
{
BiTree root = T, p = T;
BiTNode* insertnode = new BiTNode;
insertnode->data = key;
insertnode->lchild = insertnode->rchild = NULL;
if (T == NULL)
{
T = insertnode;
return T;
}
while (p)
{
if (p->data == key)
{
printf("%d has exist!\n", key);
return NULL;
}
else if (p->data > key)
{
if (p->lchild)
p = p->lchild;
else
{
p->lchild = insertnode;
printf("Insert %d\n", key);
T = root;
return insertnode;
}
}
else
{
if (p->rchild)
p = p->rchild;
else
{
p->rchild = insertnode;
printf("Insert %d\n", key);
T = root;
return insertnode;
}
}
}
}
//使用控制台输入的方式来创建BST
BiTree CreateBST()
{
printf("Please input number: ");
BiTree root = NULL;
while (1)
{
int key;
cin >> key;
if (key == -1)
{
printf("Creat successful ! \n");
return root;
}
InsertBST(root, key);
}
}
//找到最小的值
int FindMin(BiTree T)
{
while (T->rchild)
{
T = T->rchild;
}
return T->data;
}
//在T上删除key。成功删除则返回所要删除的节点,否则返回NULL。注意:删除实际上只是将相应节点从树上分离出来留待后用,并不一定要delete。
BiTNode* DeleteBST(BiTree& T, ElemType key)
{
//可尝试使用递归方式进行删除
if (T)
{
if (key < T->data)
T->lchild = DeleteBST(T->lchild, key);
else if (key > T->data)
T->rchild = DeleteBST(T->rchild, key);
else
{
if (T->lchild && T->rchild)
{
int minn = FindMin(T->rchild);
T->data = minn;
T->rchild = DeleteBST(T->rchild, key);
}
else
{
if (T->lchild==NULL)
T = T->rchild;
else if (T->rchild == NULL)
T = T->lchild;
}
}
}
return T;
}
void InOrder(BiTree t)
{
if (t) {
InOrder(t->lchild);
cout << t->data << " ";
InOrder(t->rchild);
}
}
void GetHigh(BiTree t)
{
queue<BiTree>q, qq;
if(t)
q.push(t);
int high = 0;
while (q.size())
{
high++;
while (q.size())
{
if (q.front()->lchild)
qq.push(q.front()->lchild);
if (q.front()->rchild)
qq.push(q.front()->rchild);
q.pop();
}
swap(q, qq);
}
printf("The high of tree is: %d\n\n", high);
}
int main() {
long beginTime = clock();//获得开始时间,单位为毫秒
//建树测试数据:50 30 80 20 40 90 10 25 35 85 23 88 -1。注意:-1代表输入结束,不插入-1。
BiTree root = CreateBST();
printf("\n");
//中序该BST应返回排序好后的数 10 20 23 25 30 35 40 50 80 85 88 90
printf("InOrder: ");
InOrder(root);
printf("\n\n");
//求树的高度:5
GetHigh(root);
//查找测试数据:25 50 90 99 说明:99为查找不成功。
printf("Search: -------------------------------------------------------------------------------------------------------- \n");
SearchBST(root, 25);
SearchBST(root, 50);
SearchBST(root, 90);
SearchBST(root, 99);
printf("\n\n");
//插入测试数据:5 100 50 说明:50已有,不用插入
printf("Insert: -------------------------------------------------------------------------------------------------------- \n");
InsertBST(root, 5);
InsertBST(root, 100);
InsertBST(root, 50);
printf("\n\n");
//删除测试数据:5 23 25 80 50 说明:5与23为左右孩子均为空;25,只有左孩子;80只有右孩子;50 左右孩子都有。
DeleteBST(root, 5);
DeleteBST(root, 23);
DeleteBST(root, 25);
DeleteBST(root, 80);
DeleteBST(root, 50);
//删除后再次中序并求一下树高度进行验证
GetHigh(root);
//测试时间
long endTime = clock();
cout << "beginTime:" << beginTime << endl
<< "endTime:" << endTime << endl
<< "endTime - beginTime:" << endTime - beginTime << "ms" << endl;
return 0;
}
参考资料
BST-基础代码
#include<iostream>
using namespace std;
typedef int ElemType;
typedef struct BiTNode {
ElemType data;
struct BiTNode* lchild, * rchild;
} BiTNode, * BiTree;
BiTNode* CreateNode(int v)
{
BiTNode* node = new BiTNode;
node->data = v;
node->lchild = NULL;
node->rchild = NULL;
return node;
}
//在T上搜索key。查找成功则返回相应节点,否则返回NULL;
BiTNode* SearchBST(BiTree T, ElemType key)
{
}
//在T上插入key。成功插入,则返回所插入节点;否则返回NULL。
BiTNode* InsertBST(BiTree &T, ElemType key)
{
}
//使用控制台输入的方式来创建BST
BiTree CreateBST()
{
}
//在T上删除key。成功删除则返回所要删除的节点,否则返回NULL。注意:删除实际上只是将相应节点从树上分离出来留待后用,并不一定要delete。
BiTNode* DeleteBST(BiTree &T, ElemType key)
{
//可尝试使用递归方式进行删除
}
void InOrder(BiTree t)
{
if (t) {
InOrder(t->lchild);
cout << t->data <<" ";
InOrder(t->rchild);
}
}
int main() {
//建树测试数据:50 30 80 20 40 90 10 25 35 85 23 88 -1。注意:-1代表输入结束,不插入-1。
//中序该BST应返回排序好后的数 10 20 23 25 30 35 40 50 80 85 88 90
//求树的高度:5
//查找测试数据:25 50 90 99 说明:99为查找不成功。
//插入测试数据:5 100 50 说明:50已有,不用插入
//删除测试数据:5 23 25 80 50 说明:5与23为左右孩子均为空;25,只有左孩子;80只有右孩子;50 左右孩子都有。
//删除后再次中序并求一下树高度进行验证
return 0;
}
c++测试运行时间
#include<iostream>
#include<time.h>
using namespace std;
//原文地址:http://blog.csdn.net/lincyang/article/details/6028057
int main()
{
long beginTime =clock();//获得开始时间,单位为毫秒
for(int i=0;i<10000;i++){cout<<i<<endl;}//输出10000行数字
long endTime=clock();//获得结束时间
cout<<"beginTime:"<<beginTime<<endl
<<"endTime:"<<endTime<<endl
<<"endTime-beginTime:"<<endTime-beginTime<<"ms"<<endl;
return 0;
}
```'
### STL_Map_Demo
```cpp
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<string, int> myMap;
myMap["a"] = 10; //存入键值对(key-value):a->10
myMap["b"] = 20;
map<string, int>::iterator iter = myMap.find("a"); //iterator是map的迭代器,可通过其查找元素
if (iter != myMap.end())
{
cout<<"Found!key = "<<iter->first<<", value= "<<iter->second<<endl;;
}
else
{
cout<<"Not Found!"<<endl;
}
/*也可直接使用myMap["a"]形式获取map里面的value。但有缺点,还是建议使用*/
//cout<<myMap["a"]<<endl;
//cout<<myMap["x"]<<endl;
cout<<"Travsing myMap"<<endl;
//使用迭代器遍历map
for(iter = myMap.begin(); iter!= myMap.end(); iter++)
{
cout<<"key = "<<iter->first<<", value= "<<iter->second<<endl;
}
return 0;
}