How do I reduce cognitive complexity of the if statements in the while loop? This is a code for inserting a node to a threaded binary search tree. This is my logic for the operation but the ide is giving me these issues. How do I fix them?
Refactor this method to reduce its Cognitive Complexity from 18 to the 15 allowed. [+11 locations]
Reduce the total number of break and continue statements in this loop to use at most one. [+2 locations]
Here's the code
public class threaded {
class Node{
Node left;
boolean lthread;
int data;
boolean rthread;
Node right;
Node(int data){
left = null;
lthread = true;
this.data = data;
rthread = true;
right = null;
}
}
Node root = null;
void insert(int data){
Node ptr = root;
Node par = null; // parent of the node to be inserted
while (ptr != null){
if (data == ptr.data){
System.out.println("Duplicate key");
return;
}
par = ptr;
if (data < ptr.data){
if (!ptr.lthread){
ptr = ptr.left;
}
else{
break;
}
}
else {
if (!ptr.rthread){
ptr = ptr.right;
}
else{
break;
}
}
Node tmp = new Node(data); // creating a new node
if (root == null){
root = new Node(data);
}
else if (data < par.data){
tmp.left = par.left;
tmp.right = par;
par.lthread = false;
par.left = tmp;
}
else if (data > par.data){
tmp.left = par;
tmp.right = par.right;
par.rthread = false;
par.right = tmp;
}
}
}
Cognitive Complexity is a measure of how difficult your code is to understand. It is a subjective maintainability check that measures the amount of nesting, and flow breaks there are. It is not the same as cyclomatic complexity (which is forks of logic which require unique test cases to test that branch of code) but very much close cousins. There are still some more static analysis that goes into generating a cognitive complexity score.
Rule of Thumb
Think about how many test cases you need to write in order to test your piece of code.
amount of looping, if/else, switches into their own methods
if
else // complexity 2 there can be two paths for this methods
if
if
else
else // complexity 4 there are four paths for this method
Now... combine the two... you have a whopping 8 conditions to test all your code paths!
When measuring the complexity of anything. Think about how many tests you need to write to test that method. You can reduce the cognitive complexity by deferring the complexity to smaller unit methods.
Some comments on your insert
implementation to help you on your journey
void insert(int data){
Node ptr = root;
Node par = null; // parent of the node to be inserted
while (ptr != null){
if (data == ptr.data){
System.out.println("Duplicate key");
return;
}
par = ptr;
if (data < ptr.data){
if (!ptr.lthread){
ptr = ptr.left;
}
else{ // Exit condition can you handle this in your loop conditional?
break;
}
}
else {
if (!ptr.rthread){
ptr = ptr.right;
}
else{
break;
}
}
Node tmp = new Node(data); // creating a new node
if (root == null){
root = new Node(data);
}
else if (data < par.data){ // Can you do this in a separate method? -- you might even be able to combine it with your conditions above.
tmp.left = par.left;
tmp.right = par;
par.lthread = false;
par.left = tmp;
}
else if (data > par.data){ // Can you do this in a separate method? append()? if you combine it with your conditional above -- you can go appendLeft(), appendRight()
tmp.left = par;
tmp.right = par.right;
par.rthread = false;
par.right = tmp;
}
}
}
Pseudo code it to figure out how you want to write the methods in your insert loop.