// File: /workspace/github_cpp_makefile_star2_O3/DaCasBe[P]Gestion-de-asignaturas-mediante-arboles-binarios-ordenados/nodoEnlazadoArbolBinarioEstudiante.cpp
// Function: ed::NodoEnlazadoArbolBinarioEstudiante::remove(ed::Estudiante const&)
void ed::NodoEnlazadoArbolBinarioEstudiante::remove(ed::Estudiante const &item){
	ed::Estudiante e(item); //Creamos un estudiante auxiliar
	
	//Precondición
	#ifndef NDEBUG
		assert(exists(e));
	#endif
	
	if(item==getItem()){ //El nodo actual contiene el ítem a eliminar
		ed::NodoEnlazadoArbolBinarioEstudiante * auxiliar; //Creamos un nodo auxiliar
		
		if(!hasLeftTree() and !hasRightTree()){ //El nodo actual no tiene hijos
			if(hasParent()){ //El nodo actual tiene padre
				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(NULL);
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(NULL);
				}
				
				//Borramos el ítem del nodo actual
				delete _item;
				_item=NULL;
			}
			
			else{ //El nodo atual no tiene padre
				//Borramos el ítem del nodo actual
				_item=NULL;
			}
		}

		else if(hasLeftTree() and !hasRightTree()){ //El nodo actual sólo tiene hijo izquierdo
			if(hasParent()){ //El nodo actual tiene padre
				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(getLeftTree());
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(getLeftTree());
				}
				
				getLeftTree()->setParent(getParent()); //Enlazamos el hijo del nodo actual con el padre de este
				
				_item=NULL; //Borramos el ítem el nodo actual
				
				//Desenlazamos y borramos el nodo actual
				auxiliar=this;
				auxiliar->setParent(NULL);
				auxiliar->setLeftTree(NULL);
				
				delete auxiliar;
			}

			else{ //El nodo actual no tiene padre
				*this=*getLeftTree(); //Hacemos que el nodo actual sea el hijo
				
				//Desenlazamos el nodo actual
				getParent()->setLeftTree(NULL);
				setParent(NULL);
			}
		}

		else if(!hasLeftTree() and hasRightTree()){ //El nodo actual sólo tiene hijo derecho
			if(hasParent()){ //El nodo actual tiene padre

				if(getParent()->getLeftTree()==this){ //El nodo actual es el hijo izquierdo de su padre
					getParent()->setLeftTree(getRightTree());
				}

				else{ //El nodo actual es el hijo derecho de su padre
					getParent()->setRightTree(getRightTree());
				}

				getRightTree()->setParent(getParent()); //Enlazamos el hijo del nodo actual con el padre de este
				
				_item=NULL; //Borramos el ítem el nodo actual
				
				//Desenlazamos y borramos el nodo actual
				auxiliar=this;
				auxiliar->setParent(NULL);
				auxiliar->setRightTree(NULL);
			
				delete auxiliar;
				
			}

			else{ //El nodo actual no tiene padre
				*this=*getRightTree(); //Hacemos que el nodo actual sea el hijo
				
				//Desenlazamos el nodo actual
				getParent()->setRightTree(NULL);
				setParent(NULL);
			}
		}

		else{ //El nodo actual tiene hijo izquierdo y hijo derecho
			setItem(getRightTree()->getMinor()); //Asignamos al nodo actual el ítem del descendiente menor de su hijo derecho
			getRightTree()->remove(getRightTree()->getMinor()); //Borramos el ítem del descendiente menor del hijo derecho del nodo actual
		}
	}

	else if(item<getItem()){ //El ítem es menor que el ítem del nodo actual
		getLeftTree()->remove(item); //Borramos el ítem en el subárbol hijo izquierdo
	}

	else{ //El ítem es mayor que el ítem del nodo actual
		getRightTree()->remove(item); //Borramos el ítem en el subárbol hijo derecho
	}

	//Postcondición
	#ifndef NDEBUG
		assert(!exists(e));
	#endif
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x50, %rsp
movq %rsi, %r14
movq %rdi, %rbx
movq %rsp, %r15
movq %r15, %rdi
callq 0x343a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2d06
testb %al, %al
je 0x32ed
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x29a0
testb %al, %al
je 0x31a4
movq 0x10(%rbx), %rax
movq 0x18(%rbx), %rdi
testq %rax, %rax
je 0x31cf
testq %rdi, %rdi
je 0x31f7
callq 0x2e5c
movq (%rbx), %rcx
movq %rbx, %rdi
movq %rax, %rsi
callq *0x18(%rcx)
movq 0x18(%rbx), %r14
movq %r14, %rdi
callq 0x2e5c
movq %r14, %rdi
movq %rax, %rsi
callq 0x311c
jmp 0x32cc
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x2a28
xorb $0x1, %al
movzbl %al, %eax
movq 0x10(%rbx,%rax,8), %rdi
movq %r14, %rsi
callq 0x311c
jmp 0x32cc
movq 0x20(%rbx), %rax
testq %rdi, %rdi
je 0x3217
testq %rax, %rax
je 0x324b
leaq 0x18(%rbx), %rcx
cmpq %rbx, 0x10(%rax)
je 0x328b
movq %rdi, 0x18(%rax)
movq (%rcx), %rdi
jmp 0x328f
leaq 0x20(%rbx), %r14
movq 0x20(%rbx), %rcx
testq %rcx, %rcx
je 0x326d
cmpq %rbx, 0x10(%rcx)
je 0x3299
movq %rax, 0x18(%rcx)
jmp 0x32a1
testq %rax, %rax
je 0x32c1
xorl %ecx, %ecx
cmpq %rbx, 0x10(%rax)
setne %cl
movq $0x0, 0x10(%rax,%rcx,8)
leaq 0x8(%rbx), %r14
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x32c5
movq (%rdi), %rax
callq *0x8(%rax)
jmp 0x32c5
leaq 0x20(%rbx), %r14
movups 0x8(%rdi), %xmm0
movups 0x18(%rdi), %xmm1
movups %xmm1, 0x18(%rbx)
movups %xmm0, 0x8(%rbx)
movq 0x20(%rbx), %rax
movq $0x0, 0x18(%rax)
jmp 0x32c5
movups 0x8(%rax), %xmm0
movups 0x18(%rax), %xmm1
movups %xmm1, 0x18(%rbx)
movups %xmm0, 0x8(%rbx)
movq 0x20(%rbx), %rax
movq $0x0, 0x10(%rax)
jmp 0x32c5
movq %rdi, 0x10(%rax)
movq %rax, 0x20(%rdi)
leaq 0x8(%rbx), %r14
jmp 0x32a9
movq %rax, 0x10(%rcx)
movq 0x10(%rbx), %rax
movq %rcx, 0x20(%rax)
leaq 0x8(%rbx), %rcx
movq $0x0, (%r14)
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x8(%rax)
jmp 0x32cc
leaq 0x8(%rbx), %r14
movq $0x0, (%r14)
movq %rsp, %rsi
movq %rbx, %rdi
callq 0x2d06
testb %al, %al
jne 0x330c
movq %rsp, %rdi
callq 0x3508
addq $0x50, %rsp
popq %rbx
popq %r14
popq %r15
retq
leaq 0x6091(%rip), %rdi      # 0x9385
leaq 0x5e3a(%rip), %rsi      # 0x9135
leaq 0x6036(%rip), %rcx      # 0x9338
movl $0xf4, %edx
callq 0x20f0
leaq 0x6071(%rip), %rdi      # 0x9384
leaq 0x5e1b(%rip), %rsi      # 0x9135
leaq 0x6017(%rip), %rcx      # 0x9338
movl $0x15f, %edx            # imm = 0x15F
callq 0x20f0
jmp 0x332d
movq %rax, %rbx
movq %rsp, %rdi
callq 0x3508
movq %rbx, %rdi
callq 0x2230
movq %rax, %rdi
callq 0x361e