//Retorna positivo caso seja uma folha (sem filhos) para avisar para apagar os nós sem next hop acima public bool DeleteLeaf(Leaf curleaf, string prefix) { bool delete = false; if (curleaf == null) { return(false); } //Verificar para onde seguir só caso ainda não ter atingindo o destino if (prefix.Length > 0) { char next = prefix[0]; prefix = prefix.Substring(1); if (next == '0') { delete = DeleteLeaf(curleaf.GetLeft(), prefix); if (delete) { curleaf.SetLeft(null); } } else if (next == '1') { delete = DeleteLeaf(curleaf.GetRight(), prefix); if (delete) { curleaf.SetRight(null); } } //Cancelar delete progressivo caso se tenha atingido um nó a meio com next hop if (curleaf.GetNextHop() != -1 || curleaf.GetLeft() != null || curleaf.GetRight() != null) { delete = false; } } else { //Só pedir para apagar nós sem next hop anteriores caso esta seja uma folha if (curleaf.GetLeft() == null && curleaf.GetRight() == null) { delete = true; } else { curleaf.SetNextHop(-1); } } return(delete); }
public void InsertLeaf(string prefix, int nextHop) { // Caso o prefixo seja o default, insere na raiz if (prefix[0] == 'e') { root.SetNextHop(nextHop); } else { // Verifica que a raiz foi criada. Pode não ter acontecido se se estiver a inserir numa árvore vazia // Ou seja, que foi totalmente apagada if (root == null) { root = new Leaf(); } // Inicializa a variável auxiliar que vai percorrer a árvore à raiz Leaf aux = root; // Percorre a árvore para inserir o prefixo for (int i = 0; i < prefix.Length; i++) { if (prefix[i] == '1') { if (aux.GetRight() == null) { aux.SetRight(new Leaf()); } aux = aux.GetRight(); } else if (prefix[i] == '0') { if (aux.GetLeft() == null) { aux.SetLeft(new Leaf()); } aux = aux.GetLeft(); } else { Console.WriteLine("There's an error in the prefix you tried to insert. Please fix it by only using the binary numeral system."); return; } } aux.SetNextHop(nextHop); } }
public bool DeleteDefault(Leaf curLeaf, int newDefault) { bool delete; if (curLeaf == null) { return(false); } // Inicializar a variável que vai percorrer a árvore à raiz if (curLeaf.GetNextHop() == newDefault) { return(true); } if (curLeaf.GetLeft() != null) { delete = DeleteDefault(curLeaf.GetLeft(), newDefault); // O garbage collector vai apagar os nós seguintes ao pôr a raíz de cada sub-árvore a null if (delete) { curLeaf.SetLeft(null); } } if (curLeaf.GetRight() != null) { delete = DeleteDefault(curLeaf.GetRight(), newDefault); if (delete) { curLeaf.SetRight(null); } } return(false); }
public List <int> ORTCIter(Leaf curLeaf, int nextHop) { List <int> leftVal, rightVal; //Atualizar valor do next hop a propagar if (curLeaf.GetNextHop() != -1) { nextHop = curLeaf.GetNextHop(); } //Verificar se nos encontramos num nó só com um filho e adicionar um caso seja esse o caso if (curLeaf.GetLeft() == null && curLeaf.GetRight() != null) { if (nextHop != -1) { curLeaf.SetLeft(new Leaf(nextHop)); } } else if (curLeaf.GetLeft() != null && curLeaf.GetRight() == null) { if (nextHop != -1) { curLeaf.SetRight(new Leaf(nextHop)); } } if (curLeaf.GetLeft() != null && curLeaf.GetRight() != null) { List <int> intersect = new List <int>(); leftVal = ORTCIter(curLeaf.GetLeft(), nextHop); rightVal = ORTCIter(curLeaf.GetRight(), nextHop); // Caso não seja uma folha, é necessário eliminar o Next Hop do nó atual curLeaf.SetNextHop(-1); //Verificar se toda a lista contenha o mesmo nexthop, caso sim pode-se truncar por aqui //facilmente verificavel caso ambos só transmitão um valor e este seja igual if (leftVal[0] == rightVal[0] && leftVal.Count == 1 && rightVal.Count == 1 && leftVal[0] != -1) { curLeaf.SetNextHop(leftVal[0]); curLeaf.SetLeft(null); curLeaf.SetRight(null); } //caso haja interseçao, manter a interseçao, caso nao manter a união intersect = leftVal.Intersect <int>(rightVal).ToList <int>(); //Mudar valor do prefixo e caso esse seja o caso para um dos valores da interseçao /*if (curLeaf == root && intersect.Count != 0) * curLeaf.SetNextHop(intersect[0]);*/ if (intersect.Count != 0) { if (intersect[0] != -1) { curLeaf.SetNextHop(intersect[0]); bool delete = DeleteDefault(curLeaf.GetLeft(), intersect[0]); if (delete) { curLeaf.SetLeft(null); } delete = DeleteDefault(curLeaf.GetRight(), intersect[0]); if (delete) { curLeaf.SetRight(null); } } } else { intersect = leftVal.Union <int>(rightVal).ToList <int>(); // Para conseguirmos ter um default /*if (curLeaf == root && intersect[0] != -1) * { * curLeaf.SetNextHop(intersect[0]); * bool delete = DeleteDefault(curLeaf.GetLeft(), intersect[0]); * if (delete) * curLeaf.SetLeft(null); * delete = DeleteDefault(curLeaf.GetRight(), intersect[0]); * if (delete) * curLeaf.SetRight(null); * }*/ if (curLeaf == root && !intersect.Contains(-1)) { curLeaf.SetNextHop(intersect[0]); bool delete = DeleteDefault(curLeaf.GetLeft(), intersect[0]); if (delete) { curLeaf.SetLeft(null); } delete = DeleteDefault(curLeaf.GetRight(), intersect[0]); if (delete) { curLeaf.SetRight(null); } } } return(intersect); } else { //List<int> newList = new List<int>(); //newList.Add(nextHop); curLeaf.possibleNextHops = new List <int>(); curLeaf.possibleNextHops.Add(nextHop); return(curLeaf.possibleNextHops); } }