根据树的后序遍历与中序遍历求解树的层序遍历。
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100;
int a[maxn], b[maxn];
int N;
struct node {
int data;
node* lchild;
node* rchild;
};
node* create(int a1,int a2,int b1,int b2) {
if (a1 > a2) {
return NULL;
}
node* n= new node;
n->data = a[a2];
int i;
for (i = b1; i <= b2; i++) {
if (b[i] == a[a2]) {
break;
}
}
int num = i - b1;
n->lchild = create(a1, a1+num-1, b1, num-1);
n->rchild = create(a1+num, a2-1, num+1, b2);
return n;
}
int flag = 0;
void leorder(node* n) {
queue<node*>q;
q.push(n);
while (!q.empty()) {
node* tem = q.front();
q.pop();
printf("%d", tem->data);
flag++;
if (flag < N)printf(" ");
if (tem->lchild != NULL) {
q.push(tem->lchild);
}
if (tem->rchild != NULL) {
q.push(tem->rchild);
}
}
}
int main() {
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &a[i]);
}
for (int j = 0; j < N; j++) {
scanf("%d", &b[j]);
}
int f = N - 1;
node* k=create(0, f, 0, f);
leorder(k);
return 0;
}
不知道啥问题最后还会多输出一些奇怪的东西。。
后序遍历的最后一个结点是根节点,然后在中序遍历中找到根节点,中序遍历的根节点前面那一段是左子树,后面是右子树。然后中序遍历中找到的根节点的左边的结点数就是左子树的数目,从头以该数目数后序遍历,这些数就是后序遍历中的左子树,这些数最后一个就是左子树的根节点进行递归。
输出与要求的数相等的树的路径。大的优先,实现代码如下:
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 100;
int N, M, S;
int tem, k;
int jilu[maxn];
struct node {
int data;
vector<int>child;
}Node[maxn];
bool cmp(int a, int b) {
return Node[a].data > Node[b].data;
}
void DFS(int index, int nodenum, int sum) {
if (sum > S)return;
if (sum == S) {
if (Node[index].child.size() != 0) {
return;
}
else {
for (int i = 0; i < nodenum; i++) {
printf("%d", Node[jilu[i]].data);
if (i < nodenum - 1)printf(" ");
else printf("\n");
}
return;
}
}
for (int i = 0; i < Node[index].child.size(); i++) {
jilu[nodenum] = Node[index].child[i];
DFS(Node[index].child[i], nodenum + 1, sum + Node[jilu[nodenum]].data);
}
}
int main() {
int count;
scanf("%d%d%d", &N, &M, &S);
for (int i = 0; i < N; i++) {
scanf("%d", &Node[i].data);
}
for (int i = 0; i < M; i++) {
scanf("%d%d", &tem,&count);
for (int j = 0; j < count; j++) {
scanf("%d", &k);
Node[tem].child.push_back(k);
}
sort(Node[tem].child.begin(), Node[tem].child.end(), cmp);
}
jilu[0] = 0;
DFS(0, 1, Node[0].data);
return 0;
}
以数组的形式实现树,是树的静态实现。
读入数据后首先使用sort函数进行排序,把结点的孩子较大的那个放在前面,这样在输出时就会优先输出大的那个孩子的路径,满足题目的要求。使用sort函数记得添加algorithm头文件。递归的过程为输入某结点与添加了该结点后的路径值,若路径值大于要求的数了则return,若等于但是还有孩子结点就return,若没有的话就将jilu数组中的路径打印出来并return。不然就进行递归操作,循环将该结点的孩子结点进行递归,加入jilu数组,总和记得改变。
判断是不是二叉查找树或者镜像二叉查找树。二叉查找树是左子树小于根节点,右子树大于根节点的树。所以读入数据后可以根据数据自己建立一个二叉查找树(插入过程记得根节点添加引用符号),然后自己对其进行先序遍历,与镜像先序遍历(镜像先序遍历就是在遍历子树时先遍历右子树)。若输入的序列与其存在对应的,就使用对应 的后序遍历打印出来。
并查集。实现代码如下:
#include<cstdio>
const int maxn = 100;
int n, m;
int a, b;
int father[maxn];
bool isroot[maxn];
void init(int n) {
for (int i = 1; i <= n; i++) {
father[i] = i;
isroot[i] = false;
}
}
int findfather(int x) {
if (x == father[x]) {
return x;
}
else {
int F = findfather(father[x]);
father[x] = F;
return F;
}
}
void uni(int a, int b) {
int xi = findfather(a);
int yi = findfather(b);
if (xi != yi)father[xi] = yi;
}
int main() {
scanf("%d%d", &n, &m);
init(n);
for (int i = 0; i < m; i++) {
scanf("%d%d", &a, &b);
uni(a, b);
}
for (int i = 1; i <= n; i++) {
isroot[findfather(i)] = true;
}
int count = 0;
for (int i = 1; i <= n; i++) {
count += isroot[i];
}
printf("%d", count);
return 0;
}
递归寻找根节点的过程是,如果一个结点它的父节点不是自己,那么不是根节点,然后寻找它的父节点的根节点,找到后同时将它的父节点赋值为根节点(这是为了压缩路径,优化查找时间),对所有的数据进行union函数合并后就找到了几个集合,遍历所有的数将根节点对应的isroot数组值赋值为true(hash)。然后输出这个数组的总和就是组数。
堆:父亲结点大于(大顶堆)或小于(小顶堆)子节点的完全二叉树。
哈夫曼树:树的带权路径长度最小。
哈夫曼编码:长度唯一,编码不唯一,左子树路径上为零右子树为一,叶子结点的编码唯一且组合不会混淆。