7-12哈夫曼树

哈夫曼树,第一行输入一个数n,表示叶结点的个数。

需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出哈夫曼树的带权路径长度(WPL)。

输入格式:

第一行输入一个数n,第二行输入n个叶结点(叶结点权值不超过1000,2<=n<=1000)。

输出格式:

在一行中输出WPL值。

输入样例:

5
1 2 2 5 9

输出样例:

37

 

priority_queue<int, vector<int>, greater<int>> q;

这行代码定义了一个优先队列 q,其中存储的元素类型是 int,使用的容器是 vector<int>,并且使用 greater<int> 作为比较器。

让我逐一解释:

  • priority_queue: 这是 C++ 标准库中的一个容器适配器,它提供了队列(先进先出)的接口,但是它会根据一些排序规则来决定元素的顺序。在这里,我们使用它来实现一个优先队列,即队列中的元素按照一定的规则(这里是权值大小)进行排序。

  • int: 这指定了队列中元素的类型,即队列中存储的数据是整数。

  • vector<int>: 这是指定了优先队列内部使用的容器类型。在这里,我们使用 vector 作为底层容器,因为它支持随机访问,而且在插入和删除元素时具有较好的性能。

  • greater<int>: 这是一个函数对象,用于比较队列中的元素。greater<int> 是一个函数对象,它定义了一个严格的弱序(strict weak ordering),即当 greater<int> 返回 true 时,表示第一个参数比第二个参数大。在这里,我们使用 greater<int> 作为比较器,这意味着元素按照从小到大的顺序排列,即最小的元素在队列的顶部。

综上所述,这行代码定义了一个存储整数类型元素的优先队列 q,它会根据元素的大小(即权值)从小到大进行排序。

7-11 树的遍历

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

输入格式:

输入第一行给出一个正整数N(30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

输出格式:

在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

4 1 6 3 5 7 2
#include<iostream>
using namespace std;
const int N = 1000000;
//定义结构
int T[N], S[N], num[N],n;//T后序,S中序
int id;
//后序建立二叉树
void get(int T[], int S[], int len, int p) {
    if (len < 1) {
        num [ p ] = -1;
        return;
    }
    int i = 0;
    while (T[len - 1] != S[i]) i++;
    num[p] = T[len - 1];
    id=max(id,p);
    //if(i)
        get(T, S, i, 2 * p);
    //if(len-i-1)
        get(T+i, S+i+1, len-i-1, 2 * p + 1);
}
int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> T[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> S[i];
    }
    get(T, S, n, 1);
    for (int i = 1; i <= id; i++) {
        if(num[i]>0)
        {
            cout << num[i];
            if(i<id)
                cout<<' ';
        }
    }
}

7-10 建立与遍历二叉树

以字符串的形式定义一棵二叉树的先序序列,若字符是‘#’, 表示该二叉树是空树,否则该字符是相应结点的数据元素。读入相应先序序列,建立二叉链式存储结构的二叉树,然后中序遍历该二叉树并输出结点数据。

输入格式:

字符串形式的先序序列(即结点的数据类型为单个字符)

输出格式:

中序遍历结果

输入样例:

在这里给出一组输入。例如:

ABC##DE#G##F###

输出样例:

在这里给出相应的输出。例如:

CBEGDFA
#include<iostream>
#include<string>
using namespace std;
const int N = 10001001;
//结构体的定义
struct TreeNode {
    char data;
    TreeNode* left, * right;
    TreeNode(char val) :data(val), left(nullptr), right(nullptr) {}//初始化
};
//数的建立,采用先序建立树,先根,再左,后右
TreeNode* BuildTree(const string& T, int& i) {
//const string &T 表示一个常量引用,const表示引用的是一个常量,不可以更改,&符号是表示函数可以直接访问string T,但是不可以更改它
    if (i >= T.length()) {   //不合法判断
        return nullptr;
    }
    char val = T[i++];
    if (val == '#') {
        return nullptr;
    }
    TreeNode* root = new TreeNode(val);
    root->left = BuildTree(T, i);
    root->right = BuildTree(T, i);
    return root;
}
//中序遍历
void inorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    inorderTraversal(root->left);
    cout << root->data ;
    inorderTraversal(root->right);
}
int main() {
    string T;
    cin >> T;
    int i = 0;
    TreeNode* root = BuildTree(T, i);
    inorderTraversal(root);
    return 0;
}



/*TreeNode(char val) : data(val), left(nullptr), right(nullptr) {}是C++中的构造函数的定义。
这段代码表示了TreeNode结构体的构造函数,用于初始化TreeNode对象的数据成员。

具体来说:

char val是构造函数的参数,表示要传入的节点数据值。
data(val)表示将构造函数参数val赋值给TreeNode对象的data成员,即节点的数据值。
left(nullptr)表示将左子节点初始化为nullptr,表示刚创建的节点暂时没有左子节点。
right(nullptr)表示将右子节点初始化为nullptr,表示刚创建的节点暂时没有右子节点。*/

7-1还原二叉树

给定一棵二叉树的前序遍历序列和中序遍历序列,要求计算该二叉树的高度。

输入格式:

输入首先给出正整数 n50),为树中结点总数。随后 2 行先后给出前序和中序遍历序列,均是长度为 n 的不包含重复英文字母(区别大小写)的字符串。

输出格式:

输出为一个整数,即该二叉树的高度。

输入样例:

9
ABDFGHIEC
FDHGIBEAC

输出样例:

5
#include<iostream>
#include<string>
using namespace std;
string T, S;
//由前序和后序求深度,T是前序,S是后序
int  get(int root, int start, int end) {
	if (start > end)return 0;
	int i = start;
	while (i < end && T[root] != S[i]) i++;
	int left_deep = get(root + 1, start, i - 1);
	int right_deep = get(root + i + 1 - start, i+ 1, end);
	return   max(left_deep, right_deep) + 1;
}
int main() {
	int n; cin >> n;
	cin >> T >> S;
	cout << get(0, 0, n - 1);
}

这个东西我也不理解。。。。。。。

7-4 根据后序和中序遍历输出前序遍历

 
 

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的前序遍历结果。

输入格式:

第一行给出正整数 n (30),是树中结点的个数。随后两行,每行给出 n 个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:

在一行中输出Preorder: 以及该树的前序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

Preorder: 4 1 3 2 6 5 7
#include<iostream>
using namespace std;
const int N = 100;
//定义结构
int T[N], S[N], num[N], n,id=0;//T后序,S中序
//后序建立二叉树
void get(int root ,int start, int end){
    if (end < start) {
        return;
    }
    int i = end;
    while (i>start&&T[root] != S[i]) i--;
    num[id++]=T[root];
    get(root-1+i-end,start, i-1);
    get(root-1,i+1,end);
}
int main() {
    int n; cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> T[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> S[i];
    }
    cout<<"Preorder: ";
    get(n-1,0,n-1);
    for(int i=0;i<id-1;i++){
        cout<<num[i]<<" ";
    }cout<<num[id-1];
    
}

7-9 交换二叉树中每个结点的左孩子和右孩子

以二叉链表作为二叉树的存储结构,交换二叉树中每个结点的左孩子和右孩子。

输入格式:

输入二叉树的先序序列。

提示:一棵二叉树的先序序列是一个字符串,若字符是‘#’,表示该二叉树是空树,否则该字符是相应结点的数据元素。

输出格式:

输出有两行:

第一行是原二叉树的中序遍历序列;

第二行是交换后的二叉树的中序遍历序列。

输入样例:

ABC##DE#G##F###

输出样例:

CBEGDFA

AFDGEBC

#include <iostream>
#include <string>
using namespace std;

struct TreeNode {
    char data;
    TreeNode *right, *left;
    TreeNode(char val) : data(val), right(nullptr), left(nullptr) {}
};
typedef struct TreeNode TreeNode;

TreeNode* BuildTree(const string &T, int& i) {
    if (i >= T.length()) return nullptr;
    char val = T[i++];
    if (val == '#') return nullptr;
    TreeNode* root = new TreeNode(val);
    root->left = BuildTree(T, i);
    root->right = BuildTree(T, i);
    return root;
}

void inorderTraversal(TreeNode* root) {
    if (!root) return;
    inorderTraversal(root->left);
    cout << root->data;
    inorderTraversal(root->right);
}

// 交换每个节点的左右子树
void swapChildren(TreeNode* root) {
    if (!root) return;
    swapChildren(root->left);
    swapChildren(root->right);
    TreeNode* temp = root->left;
    root->left = root->right;
    root->right = temp;
}

int main() {
    string S;
    cin >> S;
    int index = 0;
    TreeNode* root = BuildTree(S, index);

    // 输出原始二叉树的中序遍历
    inorderTraversal(root);
    cout << endl;

    // 交换每个节点的左右子树
    swapChildren(root);

    // 输出交换后的二叉树的中序遍历
    inorderTraversal(root);
    
    return 0;
}

 

posted on 2024-05-29 21:50  fafrkvit  阅读(114)  评论(2编辑  收藏  举报