All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.imglib2.util.Partition Maven / Gradle / Ivy

There is a newer version: 7.1.4
Show newest version
/*
 * #%L
 * ImgLib2: a general-purpose, multidimensional image processing library.
 * %%
 * Copyright (C) 2009 - 2024 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld,
 * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke,
 * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner,
 * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert,
 * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin,
 * Jean-Yves Tinevez and Michael Zinsmaier.
 * %%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * #L%
 */

package net.imglib2.util;

import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;

/**
 * TODO
 *
 */
public class Partition
{
	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final byte[] values )
	{
		final int pivotIndex = j;
		final byte pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final byte ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final byte tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final byte tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final short[] values )
	{
		final int pivotIndex = j;
		final short pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final short ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final short tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final short tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final int[] values )
	{
		final int pivotIndex = j;
		final int pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final int ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final int tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final int tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final long[] values )
	{
		final int pivotIndex = j;
		final long pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final long ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final long tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final long tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final float[] values )
	{
		final int pivotIndex = j;
		final float pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final float ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final float tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final float tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final double[] values )
	{
		final int pivotIndex = j;
		final double pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final double ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final double tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final double tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a subarray of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of subarray
	 * @param j
	 *            index of last element of subarray
	 * @param values
	 *            array
	 * @return index of pivot element
	 */
	public static int partitionSubList( int i, int j, final char[] values )
	{
		final int pivotIndex = j;
		final char pivot = values[ j-- ];

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final char ti = values[ i ];
				if ( ti >= pivot )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final char tj = values[ j ];
				if ( tj < pivot )
				{
					// swap [j] with [i]
					final char tmp = values[ i ];
					values[ i ] = values[ j ];
					values[ j ] = tmp;
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		if ( i != pivotIndex )
		{
			values[ pivotIndex ] = values[ i ];
			values[ i ] = pivot;
		}
		return i;
	}

	/**
	 * Partition a sublist of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of the sublist
	 * @param j
	 *            index of last element of the sublist
	 * @param values
	 *            the list
	 * @param compare
	 *            ordering function on T
	 * @return index of pivot element
	 */
	public static < T > int partitionSubList( int i, int j, final List< T > values, final Comparator< ? super T > compare )
	{
		final int pivotIndex = j;
		final T pivot = values.get( j-- );

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final T ti = values.get( i );
				if ( compare.compare( ti, pivot ) >= 0 )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final T tj = values.get( j );
				if ( compare.compare( tj, pivot ) < 0 )
				{
					// swap [j] with [i]
					final T tmp = values.get( i );
					values.set( i, values.get( j ) );
					values.set( j, tmp );
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		// check whether the element at iLastIndex is <
		if ( i != pivotIndex )
		{
			values.set( pivotIndex, values.get( i ) );
			values.set( i, pivot );
		}
		return i;
	}

	/**
	 * Partition a sublist of {@code values}.
	 *
	 * The element at index {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * @param i
	 *            index of first element of the sublist
	 * @param j
	 *            index of last element of the sublist
	 * @param values
	 *            the list
	 * @return index of pivot element
	 */
	public static < T extends Comparable< T > > int partitionSubList( int i, int j, final List< T > values )
	{
		final int pivotIndex = j;
		final T pivot = values.get( j-- );

		A: while ( true )
		{
			// move i forward while < pivot (and not at j)
			while ( i <= j )
			{
				final T ti = values.get( i );
				if ( ti.compareTo( pivot ) >= 0 )
					break;
				++i;
			}
			// now [i] is the place where the next value < pivot is to be
			// inserted

			if ( i > j )
				break;

			// move j backward while >= pivot (and not at i)
			while ( true )
			{
				final T tj = values.get( j );
				if ( tj.compareTo( pivot ) < 0 )
				{
					// swap [j] with [i]
					final T tmp = values.get( i );
					values.set( i, values.get( j ) );
					values.set( j, tmp );
					++i;
					--j;
					break;
				}
				else if ( j == i )
				{
					break A;
				}
				--j;
			}
		}

		// we are done. put the pivot element here.
		// check whether the element at iLastIndex is <
		if ( i != pivotIndex )
		{
			values.set( pivotIndex, values.get( i ) );
			values.set( i, pivot );
		}
		return i;
	}

	/**
	 * Partition a sublist.
	 *
	 * The element at {@code j} is taken as the pivot value. The elements
	 * {@code [i,j]} are reordered, such that all elements before the pivot are
	 * smaller and all elements after the pivot are equal or larger than the
	 * pivot. The index of the pivot element is returned.
	 *
	 * 

* After the function returns, the iterator {@code i} is on the pivot * element. That is, {@code i.next()} gives the element after the * pivot. *

* * @param i * iterator pointing before first element of the sublist, that * is, {@code i.next()} gives you the first element. * @param j * iterator pointing behind the last element of the sublist, that * is, {@code i.previous()} gives you the last element. * @param compare * ordering function on T */ public static < T > void partitionSubList( final ListIterator< T > i, final ListIterator< T > j, final Comparator< ? super T > compare ) { final int pivotIndex = j.previousIndex(); final T pivot = j.previous(); A: while ( true ) { // move i forward while < pivot (and not at j) while ( i.nextIndex() - 1 <= j.previousIndex() ) { final T ti = i.next(); if ( compare.compare( ti, pivot ) >= 0 ) { i.previous(); break; } } // now [i] is the place where the next value < pivot is to be // inserted // (via i.next() i.set() if ( i.nextIndex() > j.previousIndex() ) break; // move j backward while >= pivot (and not at i) while ( true ) { final T tj = j.previous(); if ( compare.compare( tj, pivot ) < 0 ) { // swap [j] with [i] final T ti = i.next(); i.set( tj ); j.set( ti ); break; } else if ( j.previousIndex() == i.nextIndex() - 1 ) { break A; } } } // we are done. put the pivot element here. if ( i.nextIndex() - 1 != pivotIndex ) { for ( int c = pivotIndex - j.nextIndex() + 1; c > 0; --c ) j.next(); j.set( i.next() ); i.set( pivot ); } return; } /** * Partition a sublist. * * The element at {@code j} is taken as the pivot value. The elements * {@code [i,j]} are reordered, such that all elements before the pivot are * smaller, and all elements after the pivot are equal or larger than the * pivot. The index of the pivot element is returned. * *

* After the function returns, the iterator {@code i} is on the pivot * element. That is, {@code i.next()} gives the element after the * pivot. *

* * @param i * iterator pointing before first element of the sublist, that * is, {@code i.next()} gives you the first element. * @param j * iterator pointing behind the last element of the sublist, that * is, {@code i.previous()} gives you the last element. */ public static < T extends Comparable< T > > void partitionSubList( final ListIterator< T > i, final ListIterator< T > j ) { final int pivotIndex = j.previousIndex(); final T pivot = j.previous(); A: while ( true ) { // move i forward while < pivot (and not at j) while ( i.nextIndex() - 1 <= j.previousIndex() ) { final T ti = i.next(); if ( ti.compareTo( pivot ) >= 0 ) { i.previous(); break; } } // now [i] is the place where the next value < pivot is to be // inserted // (via i.next() i.set() if ( i.nextIndex() > j.previousIndex() ) break; // move j backward while >= pivot (and not at i) while ( true ) { final T tj = j.previous(); if ( tj.compareTo( pivot ) < 0 ) { // swap [j] with [i] final T ti = i.next(); i.set( tj ); j.set( ti ); break; } else if ( j.previousIndex() == i.nextIndex() - 1 ) { break A; } } } // we are done. put the pivot element here. if ( i.nextIndex() - 1 != pivotIndex ) { for ( int c = pivotIndex - j.nextIndex() + 1; c > 0; --c ) j.next(); j.set( i.next() ); i.set( pivot ); } return; } /** * Partition a sublist of {@code values}. * * The element at index {@code j} is taken as the pivot value. The elements * {@code [i,j]} are reordered, such that all elements before the pivot are * smaller and all elements after the pivot are equal or larger than the * pivot. The index of the pivot element is returned. * *

* The {@code permutation} array is permuted in the same way as the list. * Usually, this will be an array of indices, so that the partition * operation can be mirrored in another list: Suppose, we have a list of * keys and a lists (or several) of values. If we use * {@code partitionSubList} to sort the keys, we want to reorder the values * in the same manner. We pass an indices array [0, 1, 2, ...] and use the * permutation of the indices to permute the values list. *

* * @param i * index of first element of the sublist * @param j * index of last element of the sublist * @param values * the list * @param permutation * elements of this array are permuted in the same way as the * elements in the values list * @param compare * ordering function on T * @return index of pivot element */ public static < T > int partitionSubList( int i, int j, final List< T > values, final int[] permutation, final Comparator< ? super T > compare ) { final int pivotIndex = j; final int permutationPivot = permutation[ j ]; final T pivot = values.get( j-- ); A: while ( true ) { // move i forward while < pivot (and not at j) while ( i <= j ) { final T ti = values.get( i ); if ( compare.compare( ti, pivot ) >= 0 ) break; ++i; } // now [i] is the place where the next value < pivot is to be // inserted if ( i > j ) break; // move j backward while >= pivot (and not at i) while ( true ) { final T tj = values.get( j ); if ( compare.compare( tj, pivot ) < 0 ) { // swap [j] with [i] final int indicesTmp = permutation[ i ]; permutation[ i ] = permutation[ j ]; permutation[ j ] = indicesTmp; final T tmp = values.get( i ); values.set( i, values.get( j ) ); values.set( j, tmp ); ++i; --j; break; } else if ( j == i ) { break A; } --j; } } // we are done. put the pivot element here. // check whether the element at iLastIndex is < if ( i != pivotIndex ) { values.set( pivotIndex, values.get( i ) ); values.set( i, pivot ); permutation[ pivotIndex ] = permutation[ i ]; permutation[ i ] = permutationPivot; } return i; } /** * Partition a sublist of {@code values}. * * The element at index {@code j} is taken as the pivot value. The elements * {@code [i,j]} are reordered, such that all elements before the pivot are * smaller and all elements after the pivot are equal or larger than the * pivot. The index of the pivot element is returned. * *

* The {@code permutation} array is permuted in the same way as the list. * Usually, this will be an array of indices, so that the partition * operation can be mirrored in another list: Suppose, we have a list of * keys and a lists (or several) of values. If we use * {@code partitionSubList} to sort the keys, we want to reorder the values * in the same manner. We pass an indices array [0, 1, 2, ...] and use the * permutation of the indices to permute the values list. *

* * @param i * index of first element of the sublist * @param j * index of last element of the sublist * @param values * the list * @param permutation * elements of this array are permuted in the same way as the * elements in the values list * @return index of pivot element */ public static < T extends Comparable< T > > int partitionSubList( int i, int j, final List< T > values, final int[] permutation ) { final int pivotIndex = j; final int permutationPivot = permutation[ j ]; final T pivot = values.get( j-- ); A: while ( true ) { // move i forward while < pivot (and not at j) while ( i <= j ) { final T ti = values.get( i ); if ( ti.compareTo( pivot ) >= 0 ) break; ++i; } // now [i] is the place where the next value < pivot is to be // inserted if ( i > j ) break; // move j backward while >= pivot (and not at i) while ( true ) { final T tj = values.get( j ); if ( tj.compareTo( pivot ) < 0 ) { // swap [j] with [i] final int indicesTmp = permutation[ i ]; permutation[ i ] = permutation[ j ]; permutation[ j ] = indicesTmp; final T tmp = values.get( i ); values.set( i, values.get( j ) ); values.set( j, tmp ); ++i; --j; break; } else if ( j == i ) { break A; } --j; } } // we are done. put the pivot element here. // check whether the element at iLastIndex is < if ( i != pivotIndex ) { values.set( pivotIndex, values.get( i ) ); values.set( i, pivot ); permutation[ pivotIndex ] = permutation[ i ]; permutation[ i ] = permutationPivot; } return i; } /** * Partition a sublist. * * The element at {@code j} is taken as the pivot value. The elements * {@code [i,j]} are reordered, such that all elements before the pivot are * smaller and all elements after the pivot are equal or larger than the * pivot. The index of the pivot element is returned. * *

* After the function returns, the iterator {@code i} is on the pivot * element. That is, {@code i.next()} gives the element after the * pivot. *

* *

* The {@code permutation} array is permuted in the same way as the list. * Usually, this will be an array of indices, so that the partition * operation can be mirrored in another list: Suppose, we have a list of * keys and a lists (or several) of values. If we use * {@code partitionSubList} to sort the keys, we want to reorder the values * in the same manner. We pass an indices array [0, 1, 2, ...] and use the * permutation of the indices to permute the values list. *

* * @param i * iterator pointing before first element of the sublist, that * is, {@code i.next()} gives you the first element. * @param j * iterator pointing behind the last element of the sublist, that * is, {@code i.previous()} gives you the last element. * @param permutation * elements of this array are permuted in the same way as the * elements in the values list * @param compare * ordering function on T */ public static < T > void partitionSubList( final ListIterator< T > i, final ListIterator< T > j, final int[] permutation, final Comparator< ? super T > compare ) { final int pivotIndex = j.previousIndex(); final int permutationPivot = permutation[ pivotIndex ]; final T pivot = j.previous(); A: while ( true ) { // move i forward while < pivot (and not at j) while ( i.nextIndex() - 1 <= j.previousIndex() ) { final T ti = i.next(); if ( compare.compare( ti, pivot ) >= 0 ) { i.previous(); break; } } // now [i] is the place where the next value < pivot is to be // inserted // (via i.next() i.set() if ( i.nextIndex() > j.previousIndex() ) break; // move j backward while >= pivot (and not at i) while ( true ) { final T tj = j.previous(); if ( compare.compare( tj, pivot ) < 0 ) { // swap [j] with [i] final int iIndex = i.nextIndex(); final int jIndex = j.nextIndex(); final int indicesTmp = permutation[ iIndex ]; permutation[ iIndex ] = permutation[ jIndex ]; permutation[ jIndex ] = indicesTmp; final T ti = i.next(); i.set( tj ); j.set( ti ); break; } else if ( j.previousIndex() == i.nextIndex() - 1 ) { break A; } } } // we are done. put the pivot element here. if ( i.nextIndex() - 1 != pivotIndex ) { for ( int c = pivotIndex - j.nextIndex() + 1; c > 0; --c ) j.next(); final int iIndex = i.nextIndex(); j.set( i.next() ); i.set( pivot ); permutation[ pivotIndex ] = permutation[ iIndex ]; permutation[ iIndex ] = permutationPivot; } return; } /** * Partition a sublist. * * The element at {@code j} is taken as the pivot value. The elements * {@code [i,j]} are reordered, such that all elements before the pivot are * smaller, and all elements after the pivot are equal or larger than the * pivot. The index of the pivot element is returned. * *

* After the function returns, the iterator {@code i} is on the pivot * element. That is, {@code i.next()} gives the element after the * pivot. *

* * @param i * iterator pointing before first element of the sublist, that * is, {@code i.next()} gives you the first element. * @param j * iterator pointing behind the last element of the sublist, that * is, {@code i.previous()} gives you the last element. * @param permutation * elements of this array are permuted in the same way as the * elements in the values list */ public static < T extends Comparable< T > > void partitionSubList( final ListIterator< T > i, final ListIterator< T > j, final int[] permutation ) { final int pivotIndex = j.previousIndex(); final int permutationPivot = permutation[ pivotIndex ]; final T pivot = j.previous(); A: while ( true ) { // move i forward while < pivot (and not at j) while ( i.nextIndex() - 1 <= j.previousIndex() ) { final T ti = i.next(); if ( ti.compareTo( pivot ) >= 0 ) { i.previous(); break; } } // now [i] is the place where the next value < pivot is to be // inserted // (via i.next() i.set() if ( i.nextIndex() > j.previousIndex() ) break; // move j backward while >= pivot (and not at i) while ( true ) { final T tj = j.previous(); if ( tj.compareTo( pivot ) < 0 ) { // swap [j] with [i] final int iIndex = i.nextIndex(); final int jIndex = j.nextIndex(); final int indicesTmp = permutation[ iIndex ]; permutation[ iIndex ] = permutation[ jIndex ]; permutation[ jIndex ] = indicesTmp; final T ti = i.next(); i.set( tj ); j.set( ti ); break; } else if ( j.previousIndex() == i.nextIndex() - 1 ) { break A; } } } // we are done. put the pivot element here. if ( i.nextIndex() - 1 != pivotIndex ) { for ( int c = pivotIndex - j.nextIndex() + 1; c > 0; --c ) j.next(); final int iIndex = i.nextIndex(); j.set( i.next() ); i.set( pivot ); permutation[ pivotIndex ] = permutation[ iIndex ]; permutation[ iIndex ] = permutationPivot; } return; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy