AccionFileNode_CompareChilds: Change algorithm complexity from O(n3) to O(n2)

This commit is contained in:
2014-12-03 02:21:53 +01:00
parent 2c581b262c
commit b97bf3ca4c

View File

@@ -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,