数据结构实验九 查找(分块查找,判断二叉排序树)

一、 实验目的
1. 熟悉线性表、二叉排序树和散列表的查找
2. 能够编写一些查找的算法
二、 实验内容
1 . 18个记录的关键字为22、12、13、8、9、20、33、42、44、38、24、48、60、58、74、49、86、53,编写分块查找的算法进行查找。

//fenkuai.h
//分块查找
#include<iostream>
using namespace std;

struct table  //需要查找的表
{
    int r[100];
    int length;
};

struct indexitem //索引表的一个元素
{
    int key;
    int stadr;
};

struct indextable //索引表
{
    indexitem elem[51];
    int length;
};

void create(table &st,indextable &id,int n,int m)//创建查找的表和索引表,查找的表长度n,索引表长度m
{
    int i;
cout<<"请输入查找的表"<<endl;
    st.length=n;
    for(i=0;i<n;i++)cin>>st.r[i];
cout<<"请输入索引表"<<endl;
    id.length=m;
    for(i=0;i<m;i++)cin>>id.elem[i].key>>id.elem[i].stadr;
    cout<<endl;
}

int search(table &st,indextable &id,int k)//k是要查找的数字,返回他的位置
{
    int low,high,mid;
    int p=-1;
    int s,t;
    low=0;
    high=id.length-1;
    while(low<=high&&p<0) //使用折半法查找在哪一块
    {
        mid=(low+high)/2;
        if(k>id.elem[mid-1].key && k<id.elem[mid].key)
            p=mid;

        else
        {
            if(k<id.elem[mid].key)
                high=mid-1;
            else if(k>id.elem[mid].key)
                low=mid+1;
            else
                p=mid;
        }
    }

    s=id.elem[p].stadr; //确定在哪一块之后顺序查找
    if(p==id.length-1)
        t=st.length;
    else
        t=id.elem[p+1].stadr-1;
    while(k!=st.r[s]&&s<=t)
        s++;
    if(s>t)
        return 0;
    else
        return s;
}

//main.cpp
#include<iostream>
#include"fenkuai.h"
using namespace std;

int main()
{
    int ans;
    int cha;
    table st;
    indextable id;
    cout<<"请输入要查找的数"<<endl;
    cin>>cha;
    create(st,id,18,3);
    ans=search(st,id,cha);
    cout<<cha<<"的位置是"<<ans+1<<endl;
    return 0;
}

2 . 编写一个判别给定的二叉树是否为二叉排序树的算法,设二叉树以二叉链表存储表示,结点的数据域只存放正整数。

//bitree.h
//本头文件包含binode类和二叉链表bitree类
#include<iostream>
using namespace std;

template<class T>
struct binode
{
    T data;     //存储数据
    binode<T> * lchild,* rchild; //左孩子,右孩子
};

template<class T>
class bitree
{
    private:
        binode<T> * root;  //指向根节点的头指针
        int allsum;//节点总数
        int yesum;//叶子节点总数
        int a;
        binode<T> * creat(binode<T> *bt);  //构造函数调用
        void release(binode<T> *bt);  //析构函数调用
        void preorder(binode<T> *bt); //前序遍历函数调用
        void inorder(binode<T> *bt);  //中序遍历函数调用
        void postorder(binode<T> *bt);//后序遍历函数调用
        void exchange(binode<T> *bt);//交换左右子树,实验五第一问
        int sum(binode<T> *bt);//节点总数,实验五第二问
        int ysum(binode<T> *bt);//叶子节点总数,实验五第二问
        int px(binode<T> *bt);
    public:
        bitree(){root=creat(root);}  //构造函数
        ~bitree(){release(root);}     //析构函数

        void preorder(){preorder(root);} //前序遍历函数
        void inorder(){inorder(root);}  //中序遍历函数
        void postorder(){postorder(root);} //后序遍历函数
        void exchange(){exchange(root);}//交换左右子树
        int sum(){allsum=sum(root);return allsum;}//节点总数
        int ysum(){yesum=ysum(root);return yesum;}//叶子节点总数
        int px(){a=px(root);return a;} //判断是否是二叉排序树,实验8第二问

};

template<class T>
binode<T> * bitree<T>::creat(binode<T> *bt)//建立二叉链表
{
    T ch;
    cin>>ch;
    if(ch==-1)bt=NULL;
    else
    {

        bt=new binode<T>;
        bt->data=ch;     
        bt->lchild=creat(bt->lchild);
        bt->rchild=creat(bt->rchild);
    }
    return bt;
}

template<class T>
void bitree<T>::preorder(binode<T> *bt)//前序遍历递归
{
    if(bt==NULL)return;
    else
    {
        cout<<bt->data;//先输出根节点
        preorder(bt->lchild);//前序遍历左子树
        preorder(bt->rchild);//前序遍历左子树
    }
}

template<class T>
void bitree<T>::inorder(binode<T> *bt)//中序遍历递归
{
    if(bt==NULL)return;
    else
    {
        inorder(bt->lchild);//中序遍历左子树
        cout<<bt->data;//输出根节点
        inorder(bt->rchild);//中序遍历右子树
    }
}

template<class T>
void bitree<T>::postorder(binode<T> *bt)//后序遍历递归
{
    if(bt==NULL)return;
    else
    {
        postorder(bt->lchild);//后序遍历左子树
        postorder(bt->rchild);//后序遍历右子树
        cout<<bt->data;//输出根节点
    }
}


template<class T>
void bitree<T>::release(binode<T> *bt) //释放二叉链表
{
    if(bt!=NULL)
    {
        release(bt->lchild);//释放左子树
        release(bt->rchild);//释放右子树
        delete bt;//删除根节点
    }
}

template<class T>
void bitree<T>::exchange(binode<T> *bt) //交换
{
    binode<T> *temp;
    temp=new binode<T>;
    if((bt->lchild!=NULL)&&(bt->rchild!=NULL))//左右非空
    {
    if(bt->lchild->data>bt->rchild->data)//左边的数大于右边
    {
        temp=bt->lchild;
        bt->lchild=bt->rchild;//交换
        bt->rchild=temp;
    }
    exchange(bt->lchild);//检查左子树
    exchange(bt->rchild);//检查右子树
    }
}

template<class T>
int bitree<T>::sum(binode<T> *bt)//节点总数
{
    int count=0;
    count++;//节点数量加1
    if(bt->lchild!=NULL)//左边非空,检查左边
    {
        count+=sum(bt->lchild);
    }
    if(bt->rchild!=NULL)//右边非空,检查右边
    {
        count+=sum(bt->rchild);
    }
    return count;
}

template<class T>
int bitree<T>::ysum(binode<T> *bt)//叶子节点总数
{
    int countt=0;
    if((bt->lchild==NULL)&&(bt->rchild==NULL))//当左右都空,数量加1
         countt++;

    if(bt->lchild!=NULL)//左边非空,检查左边
    {
        countt+=ysum(bt->lchild);
    }

    if(bt->rchild!=NULL)//右边非空,检查右边
    {
        countt+=ysum(bt->rchild);
    }
    return countt;
}

template<class T>
int bitree<T>::px(binode<T> *bt)//判断是否是二叉排序树
{
    int ans=0;

    if(bt->lchild!=NULL)
    {
        if(bt->lchild->data>bt->data)//如果左孩子大于根节点,说明不是二叉排序树
        {
            ans++;
            return ans;
        }
        ans+=px(bt->lchild);
    }

    if(bt->rchild!=NULL)
    {
        if(bt->rchild->data<bt->data)//如果右孩子小于根节点,说明不是二叉排序树
        {
            ans++;
            return ans;
        }
        ans+=px(bt->rchild);
    }
    return ans;//如果是二叉排序树,返回值为0
}

#include<iostream>
#include"bitree.h"
using namespace std;

int main()
{
    bitree<int> a;
    int m=0;      //实验8.2 判断是否是二叉排序树
    m=a.px();
    if(m==0)cout<<"是二叉排序树"<<endl;
    else cout<<"不是二叉排序树"<<endl;

    return 0;
}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/landcruiser007/article/details/79275196
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞