数据结构第六次试验:查找

前言

为了帮助同学们完成痛苦的实验课程设计,本作者将其作出的实验结果及代码贴至CSDN中,供同学们学习参考。如有不足或描述不完善之处,敬请各位指出,欢迎各位的斧正!

一、实验内容

第232页第三题第一小题

试写出折半查找的递归算法

B-树的插入和删除操作

二、实验环境

Dev C++或Visual Studio 2019

三、实验目的

  1. 学习并通过实验掌握折半查找
  2. 通过建立相关函数,掌握查找的方式
  3. 通过建立相关函数,学习B-树

四、算法设计

int search(datatype a[], int mn, int mx, datatype find)
{
	int mid = (mn + mx) % 2 == 0 ? (mx + mn) / 2 : (mx + mn + 1) / 2;
	if (mx >= mn)
	{
		if (a[mid] == find)return mid;
		else if (a[mn] == find)return mn;
		else if (a[mx] == find)return mx;
		else if (a[mid] > find) return(search(a, mn + 1, mid - 1, find));
		else if (a[mid] < find) return(search(a, mid + 1, mx - 1, find));
		else return 0;
	}
	else return 0;
}

在这里插入图片描述

void adjl(Tree* t)//中心右移
{
    Tree temp = NULL;
    if (*t)
    {
        temp = *t;
        *t = temp->right;
        temp->right = (*t)->left;
        (*t)->left = temp;
    }
}
void adjr(Tree* t)//中心左移
{
    Tree temp = NULL;
    if (*t)
    {
        temp = *t;
        *t = temp->left;
        temp->left = (*t)->right;
        (*t)->right = temp;
    }
}
void adjlr(Tree* t)
{
    adjl(&(*t)->left);
    adjr(t);
}
void adjrl(Tree* t)
{
    adjr(&(*t)->right);
    adjl(t);
}
void create(Tree* t, datatype x)
{
    if (!*t)//若树为空,建立根节点
    {
        *t = new TreeNode();
        (*t)->left = (*t)->right = NULL;
        (*t)->data = x;
        (*t)->height = 0;
        (*t)->del = 0;
    }
    else//若树非空
    {
        if (x < (*t)->data) //小于此节点对应数字
        {
            create(&(*t)->left, x);
            if (num((*t)->left) - num((*t)->right) == 2)//不平衡
            {
                if ((*t)->left->right == NULL)
                {
                    adjr(t);
                }
                else
                {
                    adjlr(t);
                }
            }
        }
        else if (x > (*t)->data) //大于此节点对应数字
        {
            create(&(*t)->right, x);
            if (num((*t)->right) - num((*t)->left) == 2)//不平衡
            {
                if ((*t)->right->left == NULL)
                {
                    adjl(t);
                }
                else
                {
                    adjrl(t);
                }
            }
        }
        (*t)->height = maxnum((*t)->left, (*t)->right) + 1;
    }
}
void dlt(Tree* t, int x)//删除子节点
{
    if (*t)
    {
        if (x < (*t)->data)
            dlt(&(*t)->left, x);
        else if (x > (*t)->data)
            dlt(&(*t)->right, x);
        else
        {
            (*t)->del = 1;
        }
    }
}

在这里插入图片描述
在这里插入图片描述

五、实验代码

作业一 绘制B-树的图
首先假设这个B-树的阶为3
在这里插入图片描述
插入关键字31
在这里插入图片描述
再插入27,则发现需要进行分裂
在这里插入图片描述
左部放在原来的结点,右部放入新的结点,而中间值则插入到父结点,并且父结点会产生一个新的指针,指向新的结点的位置
在这里插入图片描述
插入86,则发现需要进行分裂
在这里插入图片描述
进行相同操作
在这里插入图片描述
进行相同操作
在这里插入图片描述
插入8,则发现需要进行分裂
在这里插入图片描述
进行相同操作
在这里插入图片描述
进行相同操作
在这里插入图片描述
进行相同操作
在这里插入图片描述
进行删除操作
在这里插入图片描述
删除13
在这里插入图片描述
删除51,关键字个数n等于[m/2]-1,而且该结点相邻的右兄弟(或左兄弟)结点中的关键字数目大于[m/2]-1
在这里插入图片描述
删除54,关键字个数n等于[m/2]-1,而且被删关键字所在结点和其相邻的兄弟结点中的关键字数目均等于[m/2]-1
在这里插入图片描述

六、实验代码

#include<iostream>
#define max 100;
using namespace std;
typedef int datatype;
int search(datatype a[], int mn, int mx, datatype find)
{
	int mid = (mn + mx) % 2 == 0 ? (mx + mn) / 2 : (mx + mn + 1) / 2;
	if (mx >= mn)
	{
		if (a[mid] == find)return mid;
		else if (a[mn] == find)return mn;
		else if (a[mx] == find)return mx;
		else if (a[mid] > find) return(search(a, mn + 1, mid - 1, find));
		else if (a[mid] < find) return(search(a, mid + 1, mx - 1, find));
		else return 0;
	}
	else return 0;
}
int main() 
{
	datatype n; n = 10;
	if (n > 80) { cout << "error!"; return 0; }
	datatype a[100] = {0};
	datatype b[10] = {1,2,4,8,13,28,46,68,72,91};
	datatype find = 1;
	int t = 0,min=1;
	while (b[t] != '\0')
	{
		a[t + 1] = b[t];
		t += 1;
	}
	if (search(a, min, t - 2, find))cout << search(a, min, t - 2, find);
	else cout << "error!";
	return 0;
}
#include<iostream>
using namespace std;
typedef int datatype;
typedef struct TreeNode 
{
    datatype data;
    struct TreeNode* left;
    struct TreeNode* right;
    int height;//此树所含结点的个数
    int del;//del=1显示删除
}TreeNode, *Tree;
int num(Tree t)//求此树的结点个数
{
    if (t)
    {
        return t->height;
    }
    else
    {
        return -1;
    }
}
int maxnum(Tree t1, Tree t2)//求两棵树结点个数的较大值
{
    if (num(t1) > num(t2))
        return num(t1);
    else 
        return num(t2);
}
void adjl(Tree* t)//中心右移
{
    Tree temp = NULL;
    if (*t)
    {
        temp = *t;
        *t = temp->right;
        temp->right = (*t)->left;
        (*t)->left = temp;
    }
}
void adjr(Tree* t)//中心左移
{
    Tree temp = NULL;
    if (*t)
    {
        temp = *t;
        *t = temp->left;
        temp->left = (*t)->right;
        (*t)->right = temp;
    }
}
void adjlr(Tree* t)
{
    adjl(&(*t)->left);
    adjr(t);
}
void adjrl(Tree* t)
{
    adjr(&(*t)->right);
    adjl(t);
}
void create(Tree* t, datatype x)
{
    if (!*t)//若树为空,建立根节点
    {
        *t = new TreeNode();
        (*t)->left = (*t)->right = NULL;
        (*t)->data = x;
        (*t)->height = 0;
        (*t)->del = 0;
    }
    else//若树非空
    {
        if (x < (*t)->data) //小于此节点对应数字
        {
            create(&(*t)->left, x);
            if (num((*t)->left) - num((*t)->right) == 2)//不平衡
            {
                if ((*t)->left->right == NULL)
                {
                    adjr(t);
                }
                else
                {
                    adjlr(t);
                }
            }
        }
        else if (x > (*t)->data) //大于此节点对应数字
        {
            create(&(*t)->right, x);
            if (num((*t)->right) - num((*t)->left) == 2)//不平衡
            {
                if ((*t)->right->left == NULL)
                {
                    adjl(t);
                }
                else
                {
                    adjrl(t);
                }
            }
        }
        (*t)->height = maxnum((*t)->left, (*t)->right) + 1;
    }
}
void dlt(Tree* t, int x)//删除子节点
{
    if (*t)
    {
        if (x < (*t)->data)
            dlt(&(*t)->left, x);
        else if (x > (*t)->data)
            dlt(&(*t)->right, x);
        else
        {
            (*t)->del = 1;
        }
    }
}
void print(Tree t)//递归方式遍历并输出
{
    if (t)
    {
        print(t->left);
        if (!t->del)//检测是否被删除,否则不输出
        {
            cout << t->data << " ";
        }
        print(t->right);
    }
}
int main() 
{
    int i;
    datatype num[] = {2,1,3,5,4,9,8,100,80,70,88,38,28};
    int n = 13;
    Tree t = NULL;
    for (i = 0; i < 13; i++) 
    create(&t, num[i]);
    print(t);
    cout << endl;
    dlt(&t, 8);
    print(t);
    return 0;
}

七、实验结果截图

  1. 在数:1,2,4,8,13,28,46,68,72,91中找13的序号
    在这里插入图片描述

  2. 建立B-树2,1,3,5,4,9,8,100,80,70,88,38,28
    然后删除8
    在这里插入图片描述

数据结构查找实验代码 (1) 对下列数据表,分别采用二分查找算法实现查找,给出查找过程依次所比较的元素(的下标),并以二分查找的判定树来解释。 第一组测试数据: 数据表为 (1,2,3,4,6,7,8,9,10,11,12,13,17,18,19,20,24,25,26,30,35,40,45,50,,100) 查找的元素分别为: 2,8,20, 30,50,5,15,33,110 第二组数据: 数据表为 (2,3,5,7,8,10,12,15,18,20,22,25,30,35,40,45,50,55,60, 80,100) 查找的元素分别为: 22,8,80,3,100,1,13,120 (2) 设计出在二叉排序树中插入结点的算法,在此基础上实现构建二叉排序树的算法。 测试数据:构建二叉排序树的输入序列如下: 第一组数据: 100,150,120,50,70,60,80,170,180,160,110,30,40,35,175 第二组数据: 100,70,60,80,150,120,50,160,30,40,170,180,175,35 (3) 设计算法在二叉排序树中查找指定值的结点。 测试数据:在任务中第一组测试数据所构造的二叉排序树中,分别查找下列元素: 150,70,160,190,10,55,175 (4) 设计算法在二叉排序树中删除特定值的结点。 测试数据:在任务(1)中第一组测试数据所构造的二叉排序树中,分别删除下列元素:30,150,100 (5) 已知整型数组A[1..26]递增有序,设计算法以构造一棵平衡的二叉排序树来存放该数组中的所有元素。 测试数据:数组元素分别为: 第一组数据: (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26) 第二组数据: (1,3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210,231,253,277,302,328)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Knight_V_Schumacher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值