数据结构机测二

数据结构实验之串一:KMP简单应用

int nextt[1000005];
void get_next(char str2[]) {
    int len = strlen(str2);
    nextt[0] = -1;
    int j = -1, i = 0;
    while (i < len) {
        if (j == -1 || str2[i] == str2[j]) {
            i++;
            j++;
            nextt[i] = j;
        } else
            j = nextt[j];  // 失配回溯
    }
}
int kmp(char str1[], char str2[]) {
    get_next(str2);
    int len1 = strlen(str1), len2 = strlen(str2);
    int i = 0, j = 0;
    while (i < len1 && j < len2) {
        if (j == -1 || str1[i] == str2[j]) {
            i++;
            j++;
        } else
            j = nextt[j];  // 失配回溯
    }
    if (j >= len2)
        return i - len2;
    else
        return -2;
}
int main() {
    char str1[1000005], str2[1000005];
    while (~scanf("%s", str1)) {
        scanf("%s", str2);
        printf("%d\n", kmp(str1, str2) + 1);
    }
    return 0;
}

数据结构实验之串三:KMP应用 

int a[10000001], b[10000001];
int nextt[1000001];
void get_next(int b[], int n) {
    nextt[0] = -1;
    int j = -1, i = 0;
    while (i < n) {
        if (j == -1 || b[i] == b[j]) {
            i++;
            j++;
            nextt[i] = j;
        } else
            j = nextt[j];  // 失配回溯
    }
}
int kmp(int a[], int b[], int m, int n) {
    int i = 0, j = 0;
    while (i < m && j < n) {
        if (j == -1 || a[i] == b[j])  // j==-1 不能少  因为可能失配回溯到j-1
        {
            i++;
            j++;
        } else
            j = nextt[j];  // 失配回溯
    }
    if (j >= n)
        return i + 1 - n;
    else
        return -1;
}
int main() {
    int m, n;
    scanf("%d", &m);
    for (int i = 0; i < m; i++) scanf("%d", &a[i]);

    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &b[i]);

    get_next(b, n);
    int ans1 = kmp(a, b, m, n);
    if (ans1 == -1)
        printf("-1\n");
    else {
        // 坑点 唯一的确定  不能是两个
        int ans2 = kmp(a + ans1, b, m, n);  // 二次继续匹配 查看有无二次匹配
        if (ans2 == -1)
            printf("%d %d\n", ans1, ans1 + n - 1);
        else
            printf("-1\n");
    }

    return 0;
}

二叉树的基本操作

using namespace std;
struct node {
    char c;
    node *l;
    node *r;
};
int cnt;
int leaves;
node *init() {
    node *tree;
    tree = new node;
    tree->l = tree->r = NULL;
    return tree;
}

node *create(char *s) {
    if (s[cnt++] == ',') return NULL;
    node *tree = init();
    tree->c = s[cnt - 1];
    tree->l = create(s);
    tree->r = create(s);
    return tree;
}
void show_mid(node *root) {
    if (root) {
        show_mid(root->l);
        cout << root->c;
        show_mid(root->r);
    }
}
void show_back(node *root) {
    if (root) {
        show_back(root->l);
        show_back(root->r);
        cout << root->c;
    }
}
// 计算叶子的数目
void count_leaves(node *root) {
    if (root) {
        if (!root->l && !root->r) {
            leaves++;
        } else {
            count_leaves(root->l);
            count_leaves(root->r);
        }
    }
}
// 输出二叉树的子叶
void print_leaves(node *root) {
    // 层序遍历原理 从上到下从做到右
    // 正好能按相应的的顺序输出 子叶
    queue<node *> q;
    if (root) q.push(root);
    while (!q.empty()) {
        root = q.front();  //访问队首元素
        q.pop();           //删除队首
        if (root) {
            if (root->l == NULL && root->r == NULL) cout << root->c;
            q.push(root->l);  // 左子树进入队列
            q.push(root->r);  // 右子树进入队列
        }
    }
}
// 层序遍历
void forEach(node *root)  // 队列实现
{
    queue<node *> t;
    if (root != NULL) t.push(root);
    while (!t.empty()) {
        root = t.front();
        t.pop();
        if (root) {
            cout << root->c;
            t.push(root->l);
            t.push(root->r);
        }
    }
}

数据结构实验之二叉树六:哈夫曼编码 

// A [3345] - 数据结构实验之二叉树六:哈夫曼编码
#include <bits/stdc++.h>
using namespace std;
int main() {
    char s[505];
    int cnt[505];
    int p[1000];
    while (~scanf("%s", s)) {
        memset(cnt, 0, sizeof(cnt));
        int len = strlen(s);
        int sum1 = len * 8;
        int sum2 = 0;
        for (int i = 0; i < len; i++) cnt[s[i]]++;

        int top = 0, down = 0;
        for (int i = 0; i < 505; i++) {
            if (cnt[i] != 0) p[top++] = cnt[i];
        }
        sort(p, p + top);
        while (top != down) {
            int a = p[down++];
            if (top != down) {
                int b = p[down++];
                sum2 += (a + b);
                p[top++] = a + b;
                sort(p + down, p + top);
            }
        }
        printf("%d %d %.1lf\n", sum1, sum2, sum1 * 1.0 / sum2);
    }
    return 0;
}

数据结构实验之二叉树一:树的同构 

struct tree  // 利用静态数组
{
    char data;
    int l;
    int r;
} t1[150], t2[150];

//下面来判断是否为同构
//都为空树,直接返回1;一个空一个不空,直接返回0
//都不空:结点value不同,直接0;结点相同,再看子树
//左子树同不存在,就递归调用右子树
//左子树存在,看是否相等,不相等就交换左右子树,再递归调用

int isok(int a, int b) {
    if (a == -1 && b == -1)
        return 1;
    else if ((a == -1 && b != -1) || (a != -1 && b == -1))
        return 0;
    else if (t1[a].data != t2[b].data)
        return 0;
    else if (t1[a].l == -1 && t2[b].l == -1)
        return isok(t1[a].r, t2[b].r);
    else if (t1[a].l != -1 && t2[b].l != -1 &&
             t1[t1[a].l].data == t2[t2[b].l].data)
        return (isok(t1[a].l, t2[b].l) && isok(t1[a].r, t2[b].r));
    else
        return (isok(t1[a].l, t2[b].r) && isok(t1[a].r, t2[b].l));
}
int buildtree(tree tree[], int n) {
    int root = -1;  // 不初始化会re
    char l, r;
    if (n) {
        int check[150] = {0};
        for (int i = 0; i < n; i++) {
            cin >> tree[i].data >> l >> r;
            if (l != '-') {
                tree[i].l = l - '0';
                check[tree[i].l] = 1;
            } else
                tree[i].l = -1;
            if (r != '-') {
                tree[i].r = r - '0';
                check[tree[i].r] = 1;
            } else
                tree[i].r = -1;
        }
        for (int i = 0; i < n; i++) {
            if (!check[i]) {
                root = i;
                break;
            }
        }
    }
    return root;
}
int main() {
    int n, m;
    while (cin >> n) {
        int a, b;
        a = buildtree(t1, n);
        cin >> m;
        b = buildtree(t2, m);
        if (isok(a, b) == 1)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
    return 0;
}

 先序中序还原   中序后序还原

struct node {
    char c;
    node *l;
    node *r;
};

char s1[55], s2[55];
// 先序中序 还原  s1先序  s2 中序
node *front_mid_create(int len, char *s1, char *s2) {
    if (len <= 0) return NULL;
    int i;
    for (i = 0; i < len; i++) {
        if (s2[i] == s1[0]) break;
    }
    node *tree;
    tree = new node;
    tree->c = s1[0];
    tree->l = front_mid_create(i, s1 + 1, s2);
    tree->r = front_mid_create(len - i - 1, s1 + i + 1, s2 + i + 1);
    return tree;
}
// 中序后序 还原  s1后序 s2中序
node *mid_back_create(int len, char *s1, char *s2) {
    if (len <= 0) return NULL;
    int i;
    for (i = 0; i < len; i++) {
        if (s2[i] == s1[len - 1]) break;
    }
    node *tree;
    tree = new node;
    tree->c = s1[len - 1];
    tree->l = mid_back_create(i, s1, s2);
    tree->r = mid_back_create(len - i - 1, s1 + i, s2 + i + 1);
    return tree;
}
int height(node *root) {
    if (root) {
        int lh = height(root->l);
        int rh = height(root->r);
        return lh > rh ? lh + 1 : rh + 1;
    } else {
        return 0;
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值