实验12 平衡二叉树+哈希查找


A. DS查找—二叉树平衡因子

时间限制
1s
内存限制
128MB

题目描述

二叉树用数组存储,将二叉树的结点数据依次自上而下,自左至右存储到数组中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点在数组中用0来表示。

计算二叉树每个结点的平衡因子,并按后序遍历的顺序输出结点的平衡因子。

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入

测试次数t

每组测试数据一行,数组元素个数n,后跟n个字符,二叉树的数组存储。

输出

对每组测试数据,按后序遍历的顺序输出树中结点的平衡因子(测试数据没有空树)

样例查看模式
正常显示
查看格式

输入样例1

2
6 ABC00D
24 ABCD0EF0000H00000000000I

输出

B 0
D 0
C 1
A -1
D 0
B 1
I 0
H 1
E 2
F 0
C 2
A -2

代码

#include <iostream>

using namespace std;

class BiTreeNode {
public:
    char data;
    int num;
    int deep;
    BiTreeNode *LeftChild;
    BiTreeNode *RightChild;

    BiTreeNode() : LeftChild(NULL), RightChild(NULL), num(0) {}
};

class BiTree {
private:
    BiTreeNode *Root;
    int pos;
    string strTree;

    BiTreeNode *CreateBiTree(int pos) {
        BiTreeNode *T;
        char ch;
        if (pos >= strTree.size()) return NULL;
        ch = strTree[pos];
        if (ch == '0')
            T = NULL;
        else {
            T = new BiTreeNode();
            T->data = ch;
            T->LeftChild = CreateBiTree(pos * 2 + 1);
            T->RightChild = CreateBiTree(pos * 2 + 2);
        }
        return T;
    }

    int dee(BiTreeNode *t) {
        if (!t) {
            return 0;
        }
        int m = dee(t->LeftChild);
        int n = dee(t->RightChild);
        t->deep = (m > n ? m : n) + 1;
        return t->deep;
    }

    void changeyinzi(BiTreeNode *t) {

        if (t) {
            if(t->LeftChild&&t->RightChild){
                t->num = t->LeftChild->deep - t->RightChild->deep;
                changeyinzi(t->LeftChild);
                changeyinzi(t->RightChild);
            }
            else if(t->LeftChild){
                t->num = t->LeftChild->deep ;
                changeyinzi(t->LeftChild);
            }
            else if(t->RightChild)
            {
                t->num = - t->RightChild->deep;
                changeyinzi(t->RightChild);
            }
            else t->num=0;
        }
    }

    void OutOrder(BiTreeNode *t) {
        if (t != NULL) {
            OutOrder(t->LeftChild);
            OutOrder(t->RightChild);
            cout << t->data << ' ' << t->num << endl;
        }
    }

public:
    void CreateTree(string TreeArray) {
        pos = 0;
        strTree.assign(TreeArray);
        Root = CreateBiTree(0);
    }
    void change() {
        dee(Root);
        changeyinzi(Root);
    }

    void OutOrder() { OutOrder(Root); }
};

int main() {
    int t;
    string str;
    cin >> t;
    while (t--) {
        BiTree p;
        int n;
        cin >> n;
        cin >> str;
        p.CreateTree(str);
        p.change();
        p.OutOrder();
    }
    return 0;
}

B. DS哈希查找—线性探测再散列

时间限制
1s
内存限制
128MB

题目描述

定义哈希函数为H(key) = key%11,输入表长(大于、等于11)。输入关键字集合,用线性探测再散列构建哈希表,并查找给定关键字。

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入

测试次数t

每组测试数据为:

哈希表长m、关键字个数n

n个关键字

查找次数k

k个待查关键字

输出

对每组测试数据,输出以下信息:

构造的哈希表信息,数组中没有关键字的位置输出NULL

对k个待查关键字,分别输出:0或1(0—不成功,1—成功)、比较次数、查找成功的位置(从1开始)

样例查看模式
正常显示
查看格式

输入样例1

1
12 10
22 19 21 8 9 30 33 4 15 14
4
22
56
30
17

输出

22 30 33 14 4 15 NULL NULL 19 8 21 9
1 1 1
0 6
1 6 2
0 1

代码

#include <iostream>

using namespace std;
#define  Max 10000
#define ok 1
#define error 0

int main() {
    int t;
    cin >> t;
    while (t--) {
        int m, n, i, k;
        cin >> m >> n;
        int data[100];
        int *hash = new int[m];
        for (i = 0; i < m; i++)
            hash[i] = Max;
        for (i = 0; i < n; i++) {
            cin >> data[i];
            int pos = data[i] % 11;
            if (hash[pos] == Max) hash[pos] = data[i];
            else {
                for (int j = 1; j < m - 1; j++)
                    if (hash[(pos + j) % m] == Max) {
                        hash[(pos + j) % m] = data[i];
                        break;
                    }
            }
        }
        for (i = 0; i < m; i++) {
            if (hash[i] != Max) cout << hash[i];
            else cout << "NULL";
            if (i < m - 1) cout << ' ';
            else cout << endl;
        }
        cin >> k;
        while (k--) {
            int num;
            cin >> num;
            int pos = num % 11;
            int j;
            for (j = 0;; j++) {
                if (hash[(pos + j)%m] == num) {
                    cout << ok << ' ' << j + 1 << ' ' << (pos + j)%m + 1 << endl;
                    break;
                }
                if (hash[(pos + j)%m] == Max) {
                    cout << error << ' ' << j + 1 << endl;
                    break;
                }
            }
        }
        delete[] hash;
    }
}

C. DS哈希查找—二次探测再散列

时间限制
1s
内存限制
128MB

题目描述

定义哈希函数为H(key) = key%11。输入表长(大于、等于11),输入关键字集合,用二次探测再散列构建哈希表,并查找给定关键字。

输入

测试次数t

每组测试数据格式如下:

哈希表长m、关键字个数n

n个关键字

查找次数k

k个待查关键字

输出

对每组测试数据,输出以下信息:

构造的哈希表信息,数组中没有关键字的位置输出NULL

对k个待查关键字,分别输出:

0或1(0—不成功,1—成功)、比较次数、查找成功的位置(从1开始)

样例查看模式
正常显示
查看格式

输入样例1

1
12 10
22 19 21 8 9 30 33 4 41 13
4
22
15
30
41

输出

22 9 13 NULL 4 41 NULL 30 19 8 21 33
1 1 1
0 3
1 3 8
1 6 6

代码

#include <iostream>

using namespace std;
#define  Max 10000
#define ok 1
#define error 0

int main() {
    int t;
    cin >> t;
    while (t--) {
        int m, n, i, k;
        cin >> m >> n;
        int data[100];
        int *hash = new int[m];
        for (i = 0; i < m; i++)
            hash[i] = Max;
        for (i = 0; i < n; i++) {
            cin >> data[i];
            int pos = data[i] % 11;
            if (hash[pos] == Max) hash[pos] = data[i];
            else {
                for (int j = 1; j * j < m; j++)
                    if (hash[(pos + j * j) % m] == Max) {
                        hash[(pos + j * j) % m] = data[i];
                        break;
                    } else if (hash[(pos - j * j+m) % m] == Max) {
                        hash[(pos - j * j + m) % m] = data[i];
                        break;
                    }
            }
        }
        for (i = 0; i < m; i++) {
            if (hash[i] != Max) cout << hash[i];
            else cout << "NULL";
            if (i < m - 1) cout << ' ';
            else cout << endl;
        }
        cin >> k;
        while (k--) {
            int num;
            cin >> num;
            int pos = num % 11;
            int j;
            if(hash[pos]==Max) {
                cout<<error<<' '<<1<<endl;
            }
            if(hash[pos]==num) cout<<ok<<' '<<1<<' '<<pos+1<<endl;
            for (j = 1; j * j < m; j++) {
                if (hash[(pos + j * j) % m] == num) {
                    cout << ok << ' ' << 2*j << ' ' << (pos + j * j) % m + 1 << endl;
                    break;
                } else if (hash[(pos - j * j) % m] == num) {
                    cout << ok << ' ' << 2*j + 1 << ' ' << (pos - j * j) % m + 1 << endl;
                    break;
                }
                if (hash[(pos + j*j) % m] == Max) {
                    cout << error << ' ' << 2*j << endl;
                    break;
                }
                else if(hash[(pos- j*j) % m] == Max) {
                    cout << error << ' ' << 2*j +1<< endl;
                    break;
                }
            }
        }
        delete[] hash;
    }
}

D. DS哈希查找–链地址法

时间限制
1s
内存限制
128MB

题目描述

给出一个数据序列,建立哈希表,采用求余法作为哈希函数,模数为11,哈希冲突用链地址法和表头插入

如果首次查找失败,就把数据插入到相应的位置中

实现哈希查找功能

输入

第一行输入n,表示有n个数据
第二行输入n个数据,都是自然数且互不相同,数据之间用空格隔开
第三行输入t,表示要查找t个数据
从第四行起,每行输入一个要查找的数据,都是正整数

输出

每行输出对应数据的查找结果

样例查看模式
正常显示
查看格式

输入样例1

6
11 23 39 48 75 62
6
39
52
52
63
63
52

输出

6 1
error
8 1
error
8 1
8 2

代码

#include <iostream>

using namespace std;
#define Max 1000

class Node {
public:
    int da;
    Node *next;

    Node(int a = 0) : da(a), next(NULL) {}
};

int main() {
    int n, i, t;
    cin >> n;
    int data[100];
    Node *hash[11];
    for (i = 0; i < 11; i++) {
        hash[i] = new Node(Max);
    }
    for (i = 0; i < n; i++) {
        cin >> data[i];
        int pos = data[i] % 11;
        if (hash[pos]->da == Max) {
            Node *p = new Node(data[i]);
            hash[pos]->next = p;
        } else {
            Node *p = new Node(data[i]);
            Node *q = hash[pos]->next;
            hash[pos]->next = p;
            p->next = q;
        }
    }

    cin >> t;
    while (t--) {
        int num, cnt = 0;
        cin >> num;
        int pos = num % 11;
        Node *p = hash[pos];
        while (p && p->da != num) {
            p = p->next;
            cnt++;
        }
        if (p) cout << pos << ' ' << cnt << endl;
        else {
            cout << "error" << endl;
            Node *t = new Node(num);
            Node *q = hash[pos]->next;
            hash[pos]->next = t;
            t->next = q;
        }
    }
}

E. DS哈希查找–Trie树

时间限制
1s
内存限制
128MB

题目描述

Trie树又称单词查找树,是一种树形结构,如下图所示。

在这里插入图片描述

它是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

输入的一组单词,创建Trie树。输入字符串,计算以该字符串为公共前缀的单词数。

(提示:树结点有26个指针,指向单词的下一字母结点。)

输入

测试数据有多组

每组测试数据格式为:

第一行:一行单词,单词全小写字母,且单词不会重复,单词的长度不超过10

第二行:测试公共前缀字符串数量t

后跟t行,每行一个字符串

输出

每组测试数据输出格式为:

第一行:创建的Trie树的层次遍历结果

第2~t+1行:对每行字符串,输出树中以该字符串为公共前缀的单词数。

样例查看模式
正常显示
查看格式

输入样例1

abcd abd bcd efg hig
3
ab
bc
abcde

输出

abehbcficddggd
2
1
0

代码

#include <bits/stdc++.h>

using namespace std;
int trie[100010][26];// TODO:使用Trie树模板
int cnt = 0;// TODO:结点个数
int exited[10000];

void insert(string a) {
    int i, L = a.length();
    int id, height = 0;
    for (i = 0; i < L; i++) {
        id = a[i] - 'a';
        if (trie[height][id] == 0) {
            trie[height][id] = ++cnt;
        }
        height = trie[height][id];
    }
    exited[height] = 1;
}

void Level_order() {
    int i, j, tem;
    queue<int> p;
    p.push(0);
    while (!p.empty()) {
        tem = p.front();
        p.pop();
        for (i = 0; i < 26; i++)
            if (trie[tem][i] != 0) {
                cout << char(i + 'a');
                p.push(trie[tem][i]);
            }
    }
    cout << endl;
}

int search(string str) {
    int i, L = str.length(), k = 0;
    int height = 0, id;
    for (i = 0; i < L; i++) {
        id = str[i] - 'a';
        if (trie[height][id] == 0)
            return 0;
        height = trie[height][id];
    }
    if (exited[height]) k++;
    queue<int> p;
    p.push(height);
    while (!p.empty()) {
        int tem = p.front();
        p.pop();
        for (i = 0; i < 26; i++) {
            if (trie[tem][i] != 0) {
                if (exited[trie[tem][i]]) k++;
                p.push(trie[tem][i]);
            }
        }
    }
    return k;
}

int main() {
    string sr, a;
    while (getline(cin, sr)) {
        int Len = sr.length(), i;
        for (i = 0; i < Len; i++) {
            if (sr[i] != ' ') a += sr[i];
            else {
                insert(a);
                a.clear();
            }
        }
        insert(a);
        Level_order();
        int n;
        cin >> n;
        while (n--) {
            string tem;
            cin >> tem;
            cout << search(tem) << endl;
        }
        getchar();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值