docs: 添加仓库地址到README;chore: 整理实验分析;feat: Kruskal最小生成树与图存储结构
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
// 后序线索二叉树构建(根为1)
|
||||
// 输入:n,随后 n 行,每行两个整数 l、r(0 表示无孩子)。
|
||||
// 输出:n 行,每行四个整数:lchild(i) ltag(i) rchild(i) rtag(i)
|
||||
// 规则:
|
||||
// - 若有左儿子:ltag(i)=0,lchild(i) 为左儿子编号;否则 ltag(i)=1,lchild(i) 为后序前驱,无前驱为 -2。
|
||||
// - 若有右儿子:rtag(i)=0,rchild(i) 为右儿子编号;否则 rtag(i)=1,rchild(i) 为后序后继,无后继为 -1。
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void) {
|
||||
int n;
|
||||
if (scanf("%d", &n) != 1) return 0;
|
||||
if (n <= 0) return 0;
|
||||
|
||||
int *L = (int *)malloc((n + 1) * sizeof(int));
|
||||
int *R = (int *)malloc((n + 1) * sizeof(int));
|
||||
if (!L || !R) return 0;
|
||||
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
int l, r;
|
||||
if (scanf("%d %d", &l, &r) != 2) {
|
||||
free(L); free(R);
|
||||
return 0;
|
||||
}
|
||||
L[i] = l; R[i] = r;
|
||||
}
|
||||
|
||||
// 迭代后序遍历,生成访问序列 order
|
||||
int *stack = (int *)malloc((n + 1) * sizeof(int));
|
||||
int *order = (int *)malloc(n * sizeof(int));
|
||||
if (!stack || !order) { free(L); free(R); return 0; }
|
||||
int top = 0, k = 0;
|
||||
|
||||
int cur = 1; // 根为 1
|
||||
int prev = 0; // 最近已输出的结点
|
||||
while (cur || top) {
|
||||
if (cur) {
|
||||
stack[top++] = cur;
|
||||
cur = L[cur]; // 沿左链压栈
|
||||
} else {
|
||||
int u = stack[top - 1];
|
||||
if (R[u] && prev != R[u]) {
|
||||
cur = R[u]; // 右子树存在且未处理,转向右子树
|
||||
} else {
|
||||
// 右子树为空或已处理,弹栈并记录该结点
|
||||
--top;
|
||||
order[k++] = u;
|
||||
prev = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 位置映射:pos[node] = 在后序序列中的索引
|
||||
int *pos = (int *)malloc((n + 1) * sizeof(int));
|
||||
if (!pos) { free(stack); free(order); free(L); free(R); return 0; }
|
||||
for (int i = 1; i <= n; ++i) pos[i] = -1;
|
||||
for (int i = 0; i < k; ++i) pos[order[i]] = i;
|
||||
|
||||
// 输出域与标记域
|
||||
int *outL = (int *)malloc((n + 1) * sizeof(int));
|
||||
int *ltag = (int *)malloc((n + 1) * sizeof(int));
|
||||
int *outR = (int *)malloc((n + 1) * sizeof(int));
|
||||
int *rtag = (int *)malloc((n + 1) * sizeof(int));
|
||||
if (!outL || !ltag || !outR || !rtag) {
|
||||
free(pos); free(stack); free(order); free(L); free(R);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (L[i]) { // 有左儿子
|
||||
ltag[i] = 0;
|
||||
outL[i] = L[i];
|
||||
} else { // 无左儿子,线索到后序前驱
|
||||
ltag[i] = 1;
|
||||
if (pos[i] > 0) outL[i] = order[pos[i] - 1];
|
||||
else outL[i] = -2; // 无前驱
|
||||
}
|
||||
|
||||
if (R[i]) { // 有右儿子
|
||||
rtag[i] = 0;
|
||||
outR[i] = R[i];
|
||||
} else { // 无右儿子,线索到后序后继
|
||||
rtag[i] = 1;
|
||||
if (pos[i] >= 0 && pos[i] < k - 1) outR[i] = order[pos[i] + 1];
|
||||
else outR[i] = -1; // 无后继
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
printf("%d %d %d %d\n", outL[i], ltag[i], outR[i], rtag[i]);
|
||||
}
|
||||
|
||||
free(outL); free(ltag); free(outR); free(rtag);
|
||||
free(pos); free(stack); free(order);
|
||||
free(L); free(R);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user