AccionFileNode_CompareChilds: Change algorithm complexity from O(n3) to O(n2)
This commit is contained in:
@@ -58,83 +58,91 @@ AccionFileNode *AccionFileNode_CreateNormal(FileNode *fileNodeLeft,
|
|||||||
return actionFileNode;
|
return actionFileNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AccionFileNode_CompareChilds(AccionFileNode *actionFileNodeRoot,
|
void AccionFileNode_CompareChilds(AccionFileNode *actionFileNodeRoot,
|
||||||
AccionFileNode **actionFileNodeQueue,
|
AccionFileNode **actionFileNodeQueue,
|
||||||
void (*CheckPair)(FileNode *fileNodeLeft, FileNode *fileNodeRight,
|
void (*CheckPair)(FileNode *fileNodeLeft, FileNode *fileNodeRight,
|
||||||
AccionFileNode **actionFileNodeQueue)) {
|
AccionFileNode **actionFileNodeQueue)) {
|
||||||
FileNode *fileNodeLeft, *fileNodeRight;
|
FileNode *fileNodeLeft;
|
||||||
AccionFileNode *actionFileNodeQueueStart = (*actionFileNodeQueue);
|
FileNode *fileNodeRight;
|
||||||
|
FileNode *fileNodeRightQueue;
|
||||||
|
FileNode *fileNodeRightProcessed;
|
||||||
|
FileNode *fileNodeRightPrevious;
|
||||||
|
|
||||||
// Comprobar si hay algo que comparar
|
// Check if there is something to do
|
||||||
if (!actionFileNodeRoot->left && !actionFileNodeRoot->right) {
|
if (!actionFileNodeRoot->left && !actionFileNodeRoot->right) {
|
||||||
// Nada que hacer
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterar todos los nodos de la izquierda
|
// There is no left part
|
||||||
if (actionFileNodeRoot->left) {
|
if (!actionFileNodeRoot->left) {
|
||||||
fileNodeLeft = actionFileNodeRoot->left->child;
|
|
||||||
while (fileNodeLeft) {
|
|
||||||
if (actionFileNodeRoot->right) {
|
|
||||||
fileNodeRight = actionFileNodeRoot->right->child;
|
|
||||||
while (fileNodeRight) {
|
|
||||||
if (!strcmp(fileNodeLeft->name, fileNodeRight->name)) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
fileNodeRight = fileNodeRight->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fileNodeRight = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckPair(fileNodeLeft, fileNodeRight, actionFileNodeQueue);
|
|
||||||
|
|
||||||
fileNodeLeft = fileNodeLeft->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterar todos los nodos de la derecha,
|
|
||||||
// ignorando las comparaciones ya realizadas
|
|
||||||
if (actionFileNodeRoot->right) {
|
|
||||||
fileNodeRight = actionFileNodeRoot->right->child;
|
fileNodeRight = actionFileNodeRoot->right->child;
|
||||||
while (fileNodeRight) {
|
while (fileNodeRight) {
|
||||||
int doCheck = 1;
|
|
||||||
if (actionFileNodeRoot->left) {
|
|
||||||
fileNodeLeft = actionFileNodeRoot->left->child;
|
|
||||||
while (fileNodeLeft) {
|
|
||||||
AccionFileNode *afnCheck = actionFileNodeQueueStart;
|
|
||||||
while (afnCheck) {
|
|
||||||
if (afnCheck->left == fileNodeLeft
|
|
||||||
&& afnCheck->right == fileNodeRight) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
afnCheck = afnCheck->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (afnCheck) {
|
|
||||||
doCheck = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp(fileNodeLeft->name, fileNodeRight->name)) {
|
CheckPair(NULL, fileNodeRight, actionFileNodeQueue);
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
fileNodeLeft = fileNodeLeft->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fileNodeLeft = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doCheck) {
|
|
||||||
CheckPair(fileNodeLeft, fileNodeRight, actionFileNodeQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
fileNodeRight = fileNodeRight->next;
|
fileNodeRight = fileNodeRight->next;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// There is no right part
|
||||||
|
if (!actionFileNodeRoot->right) {
|
||||||
|
fileNodeLeft = actionFileNodeRoot->left->child;
|
||||||
|
while (fileNodeLeft) {
|
||||||
|
|
||||||
|
CheckPair(fileNodeLeft, NULL, actionFileNodeQueue);
|
||||||
|
|
||||||
|
fileNodeLeft = fileNodeLeft->next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare chains
|
||||||
|
fileNodeRightQueue = actionFileNodeRoot->right->child;
|
||||||
|
fileNodeRightProcessed = NULL;
|
||||||
|
|
||||||
|
// Iterate left child FileNodes
|
||||||
|
fileNodeLeft = actionFileNodeRoot->left->child;
|
||||||
|
while (fileNodeLeft) {
|
||||||
|
fileNodeRightPrevious = NULL;
|
||||||
|
fileNodeRight = fileNodeRightQueue;
|
||||||
|
while (fileNodeRight) {
|
||||||
|
if(!strcmp(fileNodeLeft->name, fileNodeRight->name)){
|
||||||
|
// Match, extract right child FileNode to the processed chain
|
||||||
|
if(fileNodeRightPrevious) {
|
||||||
|
fileNodeRightPrevious->next = fileNodeRight->next;
|
||||||
|
}else{
|
||||||
|
fileNodeRightQueue = fileNodeRight->next;
|
||||||
|
}
|
||||||
|
fileNodeRight->next = fileNodeRightProcessed;
|
||||||
|
fileNodeRightProcessed = fileNodeRight;
|
||||||
|
|
||||||
|
CheckPair(fileNodeLeft, fileNodeRight, actionFileNodeQueue);
|
||||||
|
break;
|
||||||
|
}else{
|
||||||
|
// Next right child
|
||||||
|
fileNodeRightPrevious = fileNodeRight;
|
||||||
|
fileNodeRight = fileNodeRight->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!fileNodeRight){
|
||||||
|
CheckPair(fileNodeLeft, NULL, actionFileNodeQueue);
|
||||||
|
}
|
||||||
|
fileNodeLeft = fileNodeLeft->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate unprocessed right childs
|
||||||
|
fileNodeRight = fileNodeRightQueue;
|
||||||
|
while (fileNodeRight) {
|
||||||
|
CheckPair(NULL, fileNodeRight, actionFileNodeQueue);
|
||||||
|
fileNodeRightPrevious = fileNodeRight;
|
||||||
|
fileNodeRight = fileNodeRight->next;
|
||||||
|
fileNodeRightPrevious->next = fileNodeRightProcessed;
|
||||||
|
fileNodeRightProcessed = fileNodeRightPrevious;
|
||||||
|
}
|
||||||
|
actionFileNodeRoot->right->child = fileNodeRightProcessed;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccionFileNode_DeletePair(FileNode *fileNodeLeft, FileNode *fileNodeRight,
|
void AccionFileNode_DeletePair(FileNode *fileNodeLeft, FileNode *fileNodeRight,
|
||||||
|
|||||||
Reference in New Issue
Block a user