/// <summary> /// Separa los mayores del pivote a la izquierda, agrupa a los elementos iguales al pivote, y los menores del /// pivote los agrupa a la derecha del pivote. /// </summary> /// <param name="p">pivote IComparable</param> /// <param name="i">índice izquierdo</param> /// <param name="j">índice derecho</param> /// <returns>posición del pivote</returns> PosPiv pivotar(T p, int i, int j) { int r, k, b = j; T ab; r = k = i - 1; while (k != b) { ab = a[k + 1]; int cmp = ((IComparable)ab).CompareTo(p); if (cmp == 0) { k++; } if (cmp < 0) { a[k + 1] = a[r]; a[r] = ab; k++; r++; } if (cmp > 0) { a[k + 1] = a[b]; a[b] = ab; b--; } } PosPiv sol = new PosPiv(); sol.u = r + 1; sol.v = b; return(sol); }
/// <summary> /// Divide el problema K-esimo en un problema K-esimo de menor tamaño /// </summary> /// <param name="p"></param> /// <returns></returns> public override Problema[] Divide(Problema p) { PKesimo m = (PKesimo)p; T piv = a[m.i];//optimizable con la pseudoMediana PosPiv suv = pivotar(piv, m.i, m.j); int u = suv.u, v = suv.v; PKesimo[] subp = new PKesimo[1]; if ((m.i + m.k - 1) < u) { subp[0] = new PKesimo(m.i, u - 1, m.i + m.k - 1, false); } else { if ((v - m.i + 1) < m.k) { subp[0] = new PKesimo(v + 1, m.j, m.k - v + m.i - 1, false); } else { subp[0] = new PKesimo(m.i, m.j, m.k, true); } } return(subp); }