北京化工大学数据结构2022/12/8 作业 题解

本文深入探讨了数据结构中的Hash表及B-树的应用实践,包括线性探测法与链表法解决Hash表冲突的方法,以及3阶B-树的深度计算与构造过程。通过具体的代码实现,展示了这些数据结构在解决实际问题时的效率与灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

晚三天才想起来。。。

目录

问题 A: Hash表-线性探测法解决冲突

问题 B: 求3阶B-树的深度

问题 C: 输出3阶B-树的构造过程

问题 D: Hash表-链表法解决冲突


感觉AD其实还好,BC纯纯大模拟

可能老师真的想让咱们手搓一颗B树吧(期末应该不会考这个吧)

问题 A: Hash表-线性探测法解决冲突

#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et  cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
    char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
    if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}      
using namespace std;
const int mod=1e9+7,N=1e5+7;
vector<string> a(10,"#");
int nxt[100];
signed main(){
    int n,sum;
    cin>>n;
    fer(i,0,9){
        nxt[2*i]=i+1;
        nxt[2*i+1]=-(i+1);
    }
    fer(i,0,n-1){
        string x;
        cin>>x;
        int idx=0;
        for(int j=x.size()-1;j>x.size()-5;j--){
            idx=idx+x[j]-'0';
        }
        idx=idx%10;
        if(a[idx]=="#"){
            a[idx]=x;
        }
        else{
            int j=0;
            while(a[idx+nxt[j]]!="#") j++;
            a[idx+nxt[j]]=x;
        }
        sum=0;
    } 
    for(auto t:a){
        cout<<t<<'\n';
    }
}

问题 B: 求3阶B-树的深度

BC差不多是一道题

B树这个东西写法很多,其实正常是不太建议每个节点开两个数组存的,这样空间浪费太大了

但这么写更易于理解一点,(而且符合老师审美)

最**的就是那个裂点函数了吧,还好他没有让写删除,那个合并的函数更**

主要思路就是弄两个新的点,前一半塞一个里后一半塞一个里,中间那个塞到父节点上,然后递归裂父节点

然后特判根节点,如果根节点要裂开要造一个新的根进去

难写确实难写,,但没办法。。。

#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et  cout<<'\n'
#define xx first
#define yy second    
using namespace std;
class btnode{
public:
    int keys[4];
    btnode* child[4];
    btnode* parent;
    int n;
    int level;
    int leaf;
    btnode(){
        child[0]=nullptr;
        n=0;
        level=0;
        parent=nullptr;
        for(int i=0;i<4;++i){child[i]=nullptr,keys[i]=0;}
        leaf=1;
    }
};
int maxlevel;
class bttree{
public:
    btnode* __root;
    bttree(){__root=nullptr;}
    int __order=3;
    void pf();
    btnode* findnode(btnode* root,int key);
    int insertto(btnode* node,int key);
    void insert(int key);
    void split(btnode* node);
};
void bttree::pf(){
    queue<btnode*> q;
    if(__root!=nullptr){
        __root->level=0;
        q.push(__root);
    }
    while(q.size()){
        auto node=q.front();
        q.pop();
        for(int i=0;i<=node->n;++i){
            if(node->child[i]!=nullptr){
                node->child[i]->level=node->level+1;
                maxlevel=max(maxlevel,node->child[i]->level);
                q.push(node->child[i]);
            }
        }
    }
}
btnode* bttree::findnode(btnode* root,int key){
    if(root==nullptr) return nullptr;
    if(root->leaf) return root;
    int ind=0;
    while(ind<root->n&&root->keys[ind]<key) ind++;
    return findnode(root->child[ind],key);
}
int bttree::insertto(btnode* node,int key){
    int ind=node->n;
    while(ind>=1&&node->keys[ind-1]>key){
        node->keys[ind]=node->keys[ind-1];
        node->child[ind+1]=node->child[ind];
        ind--;
    }
    node->keys[ind]=key;
    node->n+=1;
    return ind;
}
void bttree::split(btnode* node){
    auto tmp=node;
    auto node1=new btnode();
    auto node2=new btnode();
    node1->n=1;
    node2->n=1;
    node1->leaf=node->leaf;
    node2->leaf=node->leaf;
 
    node1->keys[0]=node->keys[0];
    node1->child[0]=node->child[0];
    node1->child[1]=node->child[1];
    if(node1->child[0] != nullptr) node1->child[0]->parent = node1;
    if(node1->child[1] != nullptr) node1->child[1]->parent = node1;
 
    node2->keys[0] = (node->keys[2]);
    node2->child[0] = node->child[2];
    node2->child[1] = node->child[3];
    if(node2->child[0] != nullptr) node2->child[0]->parent = node2;
    if(node2->child[1] != nullptr) node2->child[1]->parent = node2;
 
    btnode* parent=node->parent;
    if(parent == nullptr){
        parent = new btnode();
        parent->leaf = false;
        parent->n = 1;
        parent->keys[0] = node->keys[1];
        parent->child[0] = node1;
        parent->child[1] = node2;
        node1->parent = node2->parent = parent;
        __root = parent;
    }
    else{
        int index = insertto(parent, node->keys[1]);
        parent->child[index] = node1;
        parent->child[index+1] = node2;
        node1->parent = node2->parent = parent;
        if(parent->n==__order){
            split(parent);
        }
    }
    delete tmp;
}
void bttree::insert(int key){
    if(__root==nullptr){
        __root=new btnode();
        __root->keys[0]=key;
        __root->n=1;
    }
    else{
        btnode* node=findnode(__root,key);
        insertto(node,key);
        if(node->n>=__order) split(node);
    }
}
signed main(){
    bttree B;
    int nn;
    cin>>nn;
    while(nn--){
        int t;
        cin>>t;
        B.insert(t);
    }
    B.pf();
    cout<<maxlevel+1;
}

问题 C: 输出3阶B-树的构造过程

#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et  cout<<'\n'
#define xx first
#define yy second    
using namespace std;
class btnode{
public:
    int keys[4];
    btnode* child[4];
    btnode* parent;
    int n;
    int level;
    int leaf;
    btnode(){
        child[0]=nullptr;
        n=0;
        level=0;
        parent=nullptr;
        for(int i=0;i<4;++i){child[i]=nullptr,keys[i]=0;}
        leaf=1;
    }
};
int maxlevel;
class bttree{
public:
    btnode* __root;
    bttree(){__root=nullptr;}
    int __order=3;
    void pf();
    btnode* findnode(btnode* root,int key);
    int insertto(btnode* node,int key);
    void insert(int key);
    void split(btnode* node);
    void dfs(btnode* node);
};
void bttree::dfs(btnode* node){
    if(node==nullptr) return ;
    for(int i=0;i<node->level;++i) cout<<"    ";
    for(int i=0;i<node->n;++i){
        cout<<node->keys[i]<<" ";
    }
    cout<<'\n';
    for(int i=0;i<node->n+1;++i){
        dfs(node->child[i]);
    }
}
void bttree::pf(){
    queue<btnode*> q;
    if(__root!=nullptr){
        __root->level=0;
        q.push(__root);
    }
    while(q.size()){
        auto node=q.front();
        q.pop();
        for(int i=0;i<=node->n;++i){
            if(node->child[i]!=nullptr){
                node->child[i]->level=node->level+1;
                maxlevel=max(maxlevel,node->child[i]->level);
                q.push(node->child[i]);
            }
        }
    }
    dfs(__root);
}
btnode* bttree::findnode(btnode* root,int key){
    if(root==nullptr) return nullptr;
    if(root->leaf) return root;
    int ind=0;
    while(ind<root->n&&root->keys[ind]<key) ind++;
    return findnode(root->child[ind],key);
}
int bttree::insertto(btnode* node,int key){
    int ind=node->n;
    while(ind>=1&&node->keys[ind-1]>key){
        node->keys[ind]=node->keys[ind-1];
        node->child[ind+1]=node->child[ind];
        ind--;
    }
    node->keys[ind]=key;
    node->n+=1;
    return ind;
}
void bttree::split(btnode* node){
    auto tmp=node;
    auto node1=new btnode();
    auto node2=new btnode();
    node1->n=1;
    node2->n=1;
    node1->leaf=node->leaf;
    node2->leaf=node->leaf;
 
    node1->keys[0]=node->keys[0];
    node1->child[0]=node->child[0];
    node1->child[1]=node->child[1];
    if(node1->child[0] != nullptr) node1->child[0]->parent = node1;
    if(node1->child[1] != nullptr) node1->child[1]->parent = node1;
 
    node2->keys[0] = (node->keys[2]);
    node2->child[0] = node->child[2];
    node2->child[1] = node->child[3];
    if(node2->child[0] != nullptr) node2->child[0]->parent = node2;
    if(node2->child[1] != nullptr) node2->child[1]->parent = node2;
 
    btnode* parent=node->parent;
    if(parent == nullptr){
        parent = new btnode();
        parent->leaf = false;
        parent->n = 1;
        parent->keys[0] = node->keys[1];
        parent->child[0] = node1;
        parent->child[1] = node2;
        node1->parent = node2->parent = parent;
        __root = parent;
    }
    else{
        int index = insertto(parent, node->keys[1]);
        parent->child[index] = node1;
        parent->child[index+1] = node2;
        node1->parent = node2->parent = parent;
        if(parent->n==__order){
            split(parent);
        }
    }
    delete tmp;
}
void bttree::insert(int key){
    if(__root==nullptr){
        __root=new btnode();
        __root->keys[0]=key;
        __root->n=1;
    }
    else{
        btnode* node=findnode(__root,key);
        insertto(node,key);
        if(node->n>=__order) split(node);
    }
}
signed main(){
    bttree B;
    int nn;
    cin>>nn;
    while(nn--){
        int t;
        cin>>t;
        cout << "====insert a key:" << t << endl;
        B.insert(t);
        B.pf();
        cout << "==================" << endl;
    }
}

问题 D: Hash表-链表法解决冲突

#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et  cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
    char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
    x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
    if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}      
using namespace std;
const int mod=1e9+7,N=1e5+7;
list<string> h[100];
signed main()
{
    for (int i=0;i<10;i++){
        h[i].pb("#");
    }
    int n;
    cin>>n;
    while(n--)
    {
        string s;
        cin>>s;
        int m=s.size();
        int x=0;
        fer(i,m-4,m-1)
            x+=s[i]-'0';
        x%=10;
        if(*h[x].begin() == "#"){
            h[x].pop_back();
            h[x].pb(s);
        }
        else{
            h[x].push_front(s);
        }
    }
    fer(i,0,9)
    {
        for(auto t:h[i]){
            cout<<t<<" ";
        }
        cout << '\n';
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值