This is a java program to create Prufer code for a tree. In combinatorial mathematics, the Prüfer sequence (also Prüfer code or Prüfer numbers) of a labeled tree is a unique sequence associated with the tree. The sequence for a tree on n vertices has length n – 2, and can be generated by a simple iterative algorithm.
Here is the source code of the Java Program to Create the Prufer Code for a Tree. The Java program is successfully compiled and run on a Windows system. The program output is also shown below.
package com.sanfoundry.combinatorial;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
public class PruferCode
{
public static List<Integer>[] getRandomTree2(int n, Random rnd)
{
@SuppressWarnings("unchecked")
List<Integer>[] t = new List[n];
for (int i = 0; i < n; i++)
t[i] = new ArrayList<>();
int[] p = new int[n];
for (int i = 0, j; i < n; j = rnd.nextInt(i + 1), p[i] = p[j], p[j] = i, i++)
; // random permutation
for (int i = 1; i < n; i++)
{
int parent = p[rnd.nextInt(i)];
t[parent].add(p[i]);
t[p[i]].add(parent);
}
return t;
}
public static List<Integer>[] pruferCode2Tree(int[] pruferCode)
{
int n = pruferCode.length + 2;
@SuppressWarnings("unchecked")
List<Integer>[] tree = new List[n];
for (int i = 0; i < n; i++)
tree[i] = new ArrayList<>();
int[] degree = new int[n];
Arrays.fill(degree, 1);
for (int v : pruferCode)
++degree[v];
int ptr = 0;
while (degree[ptr] != 1)
++ptr;
int leaf = ptr;
for (int v : pruferCode)
{
tree[leaf].add(v);
tree[v].add(leaf);
--degree[leaf];
--degree[v];
if (degree[v] == 1 && v < ptr)
{
leaf = v;
}
else
{
for (++ptr; ptr < n && degree[ptr] != 1; ++ptr)
;
leaf = ptr;
}
}
for (int v = 0; v < n - 1; v++)
{
if (degree[v] == 1)
{
tree[v].add(n - 1);
tree[n - 1].add(v);
}
}
return tree;
}
public static int[] tree2PruferCode(List<Integer>[] tree)
{
int n = tree.length;
int[] parent = new int[n];
parent[n - 1] = -1;
pruferDfs(tree, parent, n - 1);
int[] degree = new int[n];
int ptr = -1;
for (int i = 0; i < n; ++i)
{
degree[i] = tree[i].size();
if (degree[i] == 1 && ptr == -1)
ptr = i;
}
int[] res = new int[n - 2];
int leaf = ptr;
for (int i = 0; i < n - 2; ++i)
{
int next = parent[leaf];
res[i] = next;
--degree[next];
if (degree[next] == 1 && next < ptr)
{
leaf = next;
}
else
{
++ptr;
while (ptr < n && degree[ptr] != 1)
++ptr;
leaf = ptr;
}
}
return res;
}
static void pruferDfs(List<Integer>[] tree, int[] parent, int v)
{
for (int i = 0; i < tree[v].size(); ++i)
{
int to = tree[v].get(i);
if (to != parent[v])
{
parent[to] = v;
pruferDfs(tree, parent, to);
}
}
}
// precondition: n >= 2
public static List<Integer>[] getRandomTree(int V, Random rnd)
{
int[] a = new int[V - 2];
for (int i = 0; i < a.length; i++)
{
a[i] = rnd.nextInt(V);
}
return pruferCode2Tree(a);
}
// precondition: V >= 2, V-1 <= E <= V*(V-1)/2
public static List<Integer>[] getRandomUndirectedConnectedGraph(int V,
int E, Random rnd)
{
List<Integer>[] g = getRandomTree(V, rnd);
Set<Long> edgeSet = new LinkedHashSet<>();
for (int i = 0; i < V; i++)
{
for (int j = i + 1; j < V; j++)
{
edgeSet.add(((long) i << 32) + j);
}
}
for (int i = 0; i < V; i++)
{
for (int j : g[i])
{
edgeSet.remove(((long) i << 32) + j);
}
}
List<Long> edges = new ArrayList<>(edgeSet);
for (int x : getRandomArrangement(edges.size(), E - (V - 1), rnd))
{
long e = edges.get(x);
int u = (int) (e >>> 32);
int v = (int) e;
g[u].add(v);
g[v].add(u);
}
for (int i = 0; i < V; i++)
Collections.sort(g[i]);
return g;
}
// precondition: V >= 2, V-1 <= E <= V*(V-1)/2
public static List<Integer>[] getRandomUndirectedConnectedGraph2(int V,
int E, Random rnd)
{
List<Integer>[] g = getRandomTree(V, rnd);
Set<Long> edgeSet = new LinkedHashSet<>();
for (int i = 0; i < V; i++)
{
for (int j : g[i])
{
edgeSet.add(((long) i << 32) + j);
}
}
for (int i = 0; i < E - (V - 1); i++)
{
int u;
int v;
long edge;
while (true)
{
u = rnd.nextInt(V);
v = rnd.nextInt(V);
edge = ((long) u << 32) + v;
if (u < v && !edgeSet.contains(edge))
break;
}
edgeSet.add(edge);
g[u].add(v);
g[v].add(u);
}
for (int i = 0; i < V; i++)
Collections.sort(g[i]);
return g;
}
static int[] getRandomArrangement(int n, int m, Random rnd)
{
int[] res = new int[n];
for (int i = 0; i < n; i++)
{
res[i] = i;
}
for (int i = 0; i < m; i++)
{
int j = n - 1 - rnd.nextInt(n - i);
int t = res[i];
res[i] = res[j];
res[j] = t;
}
return Arrays.copyOf(res, m);
}
static void checkGraph(int V, int E, Random rnd)
{
List<Integer>[] g = getRandomUndirectedConnectedGraph(V, E, rnd);
int n = g.length;
int[][] a = new int[n][n];
int edges = 0;
for (int i = 0; i < n; i++)
{
for (int j : g[i])
{
++a[i][j];
++edges;
}
}
if (edges != 2 * E)
{
throw new RuntimeException();
}
for (int i = 0; i < n; i++)
{
if (a[i][i] != 0)
{
throw new RuntimeException();
}
for (int j = 0; j < n; j++)
{
if (a[i][j] != a[j][i] || a[i][j] != 0 && a[i][j] != 1)
{
throw new RuntimeException();
}
}
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter the length of code: ");
int n = sc.nextInt();
int[] code = new int[n];
for (int i = 0; i < n; i++)
{
code[i] = sc.nextInt();
}
List<Integer>[] tree = pruferCode2Tree(code);
Random rnd = new Random(1);
for (int step = 0; step < 1000; step++)
{
int V = rnd.nextInt(50) + 2;
checkGraph(V, V - 1, rnd);
checkGraph(V, V * (V - 1) / 2, rnd);
checkGraph(V, rnd.nextInt(V * (V - 1) / 2 - (V - 1) + 1) + V - 1,
rnd);
}
System.out.println("Prufer code to tree conversion: "
+ Arrays.toString(tree));
System.out.println("Tree to prufer code conversion: "
+ Arrays.toString(tree2PruferCode(tree)));
sc.close();
}
}
Output:
$ javac PruferCode.java $ java PruferCode Enter the length of code: 4 2 3 4 3 Prufer code to tree conversion: [[2], [3], [0, 4], [1, 4, 5], [2, 3], [3]] Tree to prufer code conversion: [2, 3, 4, 3] Enter the length of code: 3 2 4 3 Prufer code to tree conversion: [[2], [4], [0, 3], [2, 4], [1, 3]] Tree to prufer code conversion: [2, 4, 3] Enter the length of code: 5 3 4 5 1 6 Prufer code to tree conversion: [[3], [4, 6], [4], [0, 5], [2, 1], [3, 6], [1, 5]] Tree to prufer code conversion: [3, 4, 5, 1, 6]
Related posts:
Service Registration with Eureka
Notify User of Login From New Device or Location
Java Program to Implement AttributeList API
Java Program to Represent Graph Using Adjacency Matrix
Hướng dẫn Java Design Pattern – MVC
Object cloning trong java
Java Program to Evaluate an Expression using Stacks
Tìm hiểu về Web Service
Validate email address exists or not by Java Code
Java Program to Implement Dijkstra’s Algorithm using Set
Deploy a Spring Boot WAR into a Tomcat Server
Hướng dẫn Java Design Pattern – Singleton
Spring Boot - Internationalization
Spring Boot - Actuator
Ways to Iterate Over a List in Java
Một số từ khóa trong Java
Spring Boot - Tracing Micro Service Logs
Java Stream Filter with Lambda Expression
Lập trình đa luồng trong Java (Java Multi-threading)
Functional Interfaces in Java 8
Prevent Brute Force Authentication Attempts with Spring Security
Java Program to Implement Adjacency List
Java Program to Implement ArrayList API
Guide to java.util.concurrent.Locks
Luồng Daemon (Daemon Thread) trong Java
Đồng bộ hóa các luồng trong Java
Java Program to Construct an Expression Tree for an Infix Expression
Request a Delivery / Read Receipt in Javamail
Java Program to Solve Knapsack Problem Using Dynamic Programming
Handle EML file with JavaMail
Lấy ngày giờ hiện tại trong Java
Simultaneous Spring WebClient Calls