public void DeleteRoot(HuffQueue <T> _root) { //Se elimina primero de la lista object deleteList = _root.ReturnRoot(); NodeTable delete = (NodeTable)deleteList; listAux.Remove(delete.character); // if (Nodes > 0) { HuffQueue <T> Aux = (HuffQueue <T>)_root.Clone(); List <int> Fathers = new List <int>(); int Pos = Nodes; while (Pos > 1) { Fathers.Add(Pos); Pos /= 2; } for (int i = Fathers.Count - 1; i >= 0; i--) { if (Fathers[i] % 2 != 0) { Aux.Root = Aux.Root.NodoRight; } else { Aux.Root = Aux.Root.NodoLeft; } } _root.Root.Priority = Aux.Root.Priority; _root.Root.Data = Aux.Root.Data; List <int> Invert = new List <int>(); for (int i = Fathers.Count - 1; i >= 0; i--) { Invert.Add(Fathers[i]); } DeleteRootF(Invert, _root.Root); Order(_root.Root); Nodes--; } }
public void Insert(HuffQueue <NodeTable> valuesToInsert, HuffTree _root) { List <NodeHuffTree> listAux = new List <NodeHuffTree>(); //Validar si aún hay parejar para sacar en la cola: while (valuesToInsert.Nodes >= 2) { //Si está vacío el árbol se realiza el primer proceso de inserción: if (rootOriginal == null) { //Se sacan los dos nodos de la cola y se guardan: object first = valuesToInsert.ReturnRoot(); valuesToInsert.DeleteRoot(valuesToInsert); NodeTable firstSon = (NodeTable)first; object second = valuesToInsert.ReturnRoot(); valuesToInsert.DeleteRoot(valuesToInsert); NodeTable secondSon = (NodeTable)second; //Se crean los primeros dos nodos hermanos del HuffTree NodeHuffTree firstNewSon = new NodeHuffTree { character = firstSon.character, probability = firstSon.probability, }; NodeHuffTree secondNewSon = new NodeHuffTree { character = secondSon.character, probability = secondSon.probability, }; //Se crea la raíz por primera vez: NodeHuffTree root = new NodeHuffTree { character = "N" + proxNode.ToString(), probability = firstNewSon.probability + secondNewSon.probability, }; //Se valida quién será el hijo izquierdo y quién el hijo derecho if (secondNewSon.probability > firstNewSon.probability) { root.nodeRight = secondNewSon; root.nodeLeft = firstNewSon; } else { root.nodeRight = firstNewSon; root.nodeLeft = secondNewSon; } //Se agrega el padre a los dos hermanos: firstNewSon.nodeFather = root; secondNewSon.nodeFather = root; //Se asigna la raíz: rootOriginal = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); } //Si el árbol ya tiene algo, se realiza el siguiente proceso: else { //Se sacan los dos nodos de la cola y se guardan: object first = valuesToInsert.ReturnRoot(); valuesToInsert.DeleteRoot(valuesToInsert); NodeTable firstSon = (NodeTable)first; object second = valuesToInsert.ReturnRoot(); valuesToInsert.DeleteRoot(valuesToInsert); NodeTable secondSon = (NodeTable)second; //Se crean los dos nodos hermanos del HuffTree: NodeHuffTree firstNewSon = new NodeHuffTree { character = firstSon.character, probability = firstSon.probability, }; NodeHuffTree secondNewSon = new NodeHuffTree { character = secondSon.character, probability = secondSon.probability, }; //Se crea la nueva raíz que será padre de los dos nodos hermanos sin importar cuál sea el caso: NodeHuffTree root = new NodeHuffTree { character = "N" + proxNode.ToString(), probability = firstNewSon.probability + secondNewSon.probability, }; //Ya que tenemos los hermanos, se valida si alguno de los dos ya está en la Raiz del HuffTree: //Si hay alguno, entonces se busca en la listAux si el otro que no era igual a la raíz está: if ((rootOriginal.character == firstNewSon.character) || (rootOriginal.character == secondNewSon.character)) { bool matchOnList = false; int posMatch = 0; //Se busca en la listAux: for (int i = 0; i < listAux.Count; i++) { if ((listAux[i].character == firstNewSon.character) || (listAux[i].character == secondNewSon.character)) { matchOnList = true; posMatch = i; } } //Si se encontró, entonces se saca... se hace hermano con el que ya está en la raíz del HuffTree: if (matchOnList) { //Se obtiene el nodo de la lista y se elimina: NodeHuffTree valueMatchOnList = listAux[posMatch]; listAux.RemoveAt(posMatch); //Se hace una copia de la rootOriginal; HuffTree auxilarClone = (HuffTree)_root.Clone(); //Ya que tenemos los dos valores, solo insertamos de la manera correcta: if (valueMatchOnList.probability > auxilarClone.rootOriginal.probability) { root.nodeLeft = auxilarClone.rootOriginal; root.nodeRight = valueMatchOnList; } else { root.nodeLeft = valueMatchOnList; root.nodeRight = auxilarClone.rootOriginal; } //Se agrega el padre a los dos hermanos: valueMatchOnList.nodeFather = root; auxilarClone.rootOriginal.nodeFather = root; //Se cambia la raíz rootOriginal = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); } //Si no se encontró el otro en la lista... entonces solo se hace hermano con la raíz (el que no es igual): else { //Se hace una copia de la rootOriginal; HuffTree auxilarClone = (HuffTree)_root.Clone(); //Si es igual al firstNewSon, entonces la raíz se volverá hermano con el secondNewSon if (auxilarClone.rootOriginal.character == firstNewSon.character) { if (secondNewSon.probability > auxilarClone.rootOriginal.probability) { root.nodeLeft = auxilarClone.rootOriginal; root.nodeRight = secondNewSon; } else { root.nodeLeft = secondNewSon; root.nodeRight = auxilarClone.rootOriginal; } auxilarClone.rootOriginal.nodeFather = root; secondNewSon.nodeFather = root; } //Si es igual al secondNewSon, entonces la raíz se volverá hermano con el firstNewSon else if (auxilarClone.rootOriginal.character == secondNewSon.character) { if (firstNewSon.probability > auxilarClone.rootOriginal.probability) { root.nodeLeft = auxilarClone.rootOriginal; root.nodeRight = firstNewSon; } else { root.nodeLeft = firstNewSon; root.nodeRight = auxilarClone.rootOriginal; } auxilarClone.rootOriginal.nodeFather = root; firstNewSon.nodeFather = root; } //Se cambia la raíz rootOriginal = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); } } //Si no hay alguno, entonces: else { //Se busca en la listAux para encontrar alguno de los 2: bool matchOnList = false; for (int i = 0; i < listAux.Count; i++) { if ((listAux[i].character == firstNewSon.character) || (listAux[i].character == secondNewSon.character)) { matchOnList = true; } } //Si no se encuentra, entonces solo se inserta el root en la lista: if (!matchOnList) { if (secondNewSon.probability > firstNewSon.probability) { root.nodeLeft = firstNewSon; root.nodeRight = secondNewSon; } else { root.nodeLeft = secondNewSon; root.nodeRight = firstNewSon; } //Se agrega el padre a los dos hermanos: firstNewSon.nodeFather = root; secondNewSon.nodeFather = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); //Se inserta en la listAux listAux.Add(root); } //Si se encuentra, entonces se busca si los 2 están en la lista o si solo 1 está: else { //Se busca denuevo en la lista, pero esta vez, ambos por separado: bool matchFirstNewSon = false; int posMatchFirstNewSon = 0; for (int i = 0; i < listAux.Count; i++) { if (listAux[i].character == firstNewSon.character) { matchFirstNewSon = true; posMatchFirstNewSon = i; } } bool matchSecondNewSon = false; int posMatchSecondNewSon = 0; for (int i = 0; i < listAux.Count; i++) { if (listAux[i].character == secondNewSon.character) { matchSecondNewSon = true; posMatchSecondNewSon = i; } } //Si encuentra a los dos en la lista: if (matchFirstNewSon && matchSecondNewSon) { //Se guardan y se remueven de la lista: NodeHuffTree valueMatchOnList1 = listAux[posMatchFirstNewSon]; NodeHuffTree valueMatchOnList2 = listAux[posMatchSecondNewSon]; listAux.RemoveAt(posMatchFirstNewSon); //Se valida si no es mayor la posición, ya que se habrá eliminado: if (posMatchSecondNewSon > posMatchFirstNewSon) { posMatchSecondNewSon -= 1; } listAux.RemoveAt(posMatchSecondNewSon); //Se valida en qué posición van (izquierda, derecha): if (valueMatchOnList2.probability > valueMatchOnList1.probability) { root.nodeLeft = valueMatchOnList1; root.nodeRight = valueMatchOnList2; } else { root.nodeLeft = valueMatchOnList2; root.nodeRight = valueMatchOnList1; } //Se agrega el padre a los dos hermanos: valueMatchOnList1.nodeFather = root; valueMatchOnList2.nodeFather = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); //Se inserta en la listAux listAux.Add(root); } //Si solo se encuentra uno en la lista: else if (matchFirstNewSon || matchSecondNewSon) { //Si solo se encuentra el matchFirstNewSon if (matchFirstNewSon) { //Se guardan y se remueven de la lista: NodeHuffTree valueMatchOnList1 = listAux[posMatchFirstNewSon]; listAux.RemoveAt(posMatchFirstNewSon); //Se valida en qué posición van (izquierda, derecha): if (secondNewSon.probability > valueMatchOnList1.probability) { root.nodeLeft = valueMatchOnList1; root.nodeRight = secondNewSon; } else { root.nodeLeft = secondNewSon; root.nodeRight = valueMatchOnList1; } //Se agrega el padre a los dos hermanos: valueMatchOnList1.nodeFather = root; secondNewSon.nodeFather = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); //Se inserta en la listAux listAux.Add(root); } //Si solo se encuentra el matchSecondNewSon else if (matchSecondNewSon) { //Se guardan y se remueven de la lista: NodeHuffTree valueMatchOnList2 = listAux[posMatchSecondNewSon]; listAux.RemoveAt(posMatchSecondNewSon); //Se valida en qué posición van (izquierda, derecha): if (firstNewSon.probability > valueMatchOnList2.probability) { root.nodeLeft = valueMatchOnList2; root.nodeRight = firstNewSon; } else { root.nodeLeft = firstNewSon; root.nodeRight = valueMatchOnList2; } //Se agrega el padre a los dos hermanos: valueMatchOnList2.nodeFather = root; firstNewSon.nodeFather = root; //Se agrega el padre creado a la cola: NodeTable toInsertAgainOnQueue = new NodeTable { character = "N" + proxNode.ToString(), probability = root.probability }; proxNode++; valuesToInsert.Insert(toInsertAgainOnQueue, root.probability); //Se inserta en la listAux listAux.Add(root); } } } } } } }