Java Algorithm: Sorting

1. Insertion Sort

    1> Straight Insertion Sort: O(n^2), if the records are already sorted, then O(n).

    2> Binary Insertion Sort (Reduced comparison count)

    3> 2-Way Insertion Sort (Reduced comparison count and move record time)

    4> Shell's Sort

2. Swap Sort

    1> Bubble Sort: O(n^2)

    2> Quick Sort: O(n*lgn), If the array is already ordered, then Quick Sort degenerated to Bubble Sort.

3. Selection Sort

    1> Simple Selection Sort: O(n^2)

    2> Tree Selection Sort

    4> Heap Sort: O(n*lgn)

4. Merging Sort

5. Radix Sort

 

1. Insertion Sort

    1> Straight Insertion Sort

package edu.xmu.datastructure.sort.insertion;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class StraightInsertionSort {
    @Test
    public void insertSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);

	List<Integer> sortedIntList = StraightInsertionSort.insertSort(intList);
	assertEquals(expIntList, sortedIntList);
    }

    public static List<Integer> insertSort(List<Integer> intList) {
	List<Integer> sortedIntList = Lists.newArrayList(intList);
	for (int i = 1; i < sortedIntList.size(); i++) {
	    int valueToBeInserted = sortedIntList.get(i);
	    int indexToBeInserted = i;

	    for (int j = i - 1; j >= 0; j--) {
		if (valueToBeInserted < sortedIntList.get(j)) {
		    sortedIntList.set(j + 1, sortedIntList.get(j));
		    indexToBeInserted = j;
		} else {
		    break;
		}
	    }
	    sortedIntList.set(indexToBeInserted, valueToBeInserted);
	}

	return sortedIntList;
    }
}

    2> Binary Insertion Sort

package edu.xmu.datastructure.sort.insertion;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class BinaryInsertionSort {
    @Test
    public void insertSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);

	List<Integer> sortedIntList = BinaryInsertionSort
		.binaryInsertSort(intList);
	assertEquals(expIntList, sortedIntList);
    }

    public static List<Integer> binaryInsertSort(List<Integer> intList) {
	List<Integer> sortedIntList = Lists.newArrayList(intList);
	for (int i = 1; i < sortedIntList.size(); i++) {
	    int valueToBeInserted = sortedIntList.get(i);
	    int indexToBeInserted = searchIndexToBeInserted(i, sortedIntList);

	    // Move elements from [indexToBeInserted, i - 1] to
	    // [indexToBeInserted + 1, i]
	    for (int j = i - 1; j >= indexToBeInserted; j--) {
		if (valueToBeInserted < sortedIntList.get(j)) {
		    sortedIntList.set(j + 1, sortedIntList.get(j));
		}
	    }
	    // Insert element to indexToBeInserted position
	    sortedIntList.set(indexToBeInserted, valueToBeInserted);
	}

	return sortedIntList;
    }

    public static int searchIndexToBeInserted(int hotIndex,
	    List<Integer> sortedIntList) {
	int startIndex = 0;
	int endIndex = hotIndex - 1;

	while (startIndex <= endIndex) {
	    int middle = (startIndex + endIndex) / 2;
	    if (sortedIntList.get(hotIndex) < sortedIntList.get(middle)) {
		endIndex = middle - 1;
	    } else {
		startIndex = middle + 1;
	    }
	}

	return endIndex + 1;
    }

    @Test
    public void searchIndexToBeInsertedTest() {
	List<Integer> sortedIntList = Lists.newArrayList(1, 2, 3, 0);
	int hotIndex = 3;
	int indexToBeInserted = BinaryInsertionSort.searchIndexToBeInserted(
		hotIndex, sortedIntList);
	assertEquals(0, indexToBeInserted);

	sortedIntList = Lists.newArrayList(1, 2, 3, 4, 0);
	hotIndex = 4;
	indexToBeInserted = BinaryInsertionSort.searchIndexToBeInserted(
		hotIndex, sortedIntList);
	assertEquals(0, indexToBeInserted);

	sortedIntList = Lists.newArrayList(2, 4, 6, 8, 10);
	hotIndex = 4;
	indexToBeInserted = BinaryInsertionSort.searchIndexToBeInserted(
		hotIndex, sortedIntList);
	assertEquals(4, indexToBeInserted);

	sortedIntList = Lists.newArrayList(2, 4, 6, 8, 10, 5);
	hotIndex = 5;
	indexToBeInserted = BinaryInsertionSort.searchIndexToBeInserted(
		hotIndex, sortedIntList);
	assertEquals(2, indexToBeInserted);
    }
}

    3> Shell's Sort (When we create the deltaList=Lists.newArrayList(1), then Shell's Sort degenerated to Straight Insertion Sort).

package edu.xmu.datastructure.sort.insertion;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class ShellInsertionSort {
    @Test
    public void insertSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);
	List<Integer> deltaList = Lists.newArrayList(5, 3, 2, 1);
	for (int delta : deltaList) {
	    ShellInsertionSort.shellInsertSort(intList, delta);
	}
	assertEquals(expIntList, intList);
    }

    public static void shellInsertSort(List<Integer> intList, int delta) {
	for (int i = delta; i < intList.size(); i++) {
	    int valueToBeInserted = intList.get(i);
	    int indexToBeInserted = i;

	    for (int j = i - delta; j >= 0; j -= delta) {
		if (valueToBeInserted < intList.get(j)) {
		    intList.set(j + delta, intList.get(j));
		    indexToBeInserted = j;
		} else {
		    break;
		}
	    }
	    intList.set(indexToBeInserted, valueToBeInserted);
	}
    }
}

 

2. Swap Sort

    1> Bubble Sort

package edu.xmu.datastructure.sort.swap;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class BubbleSort {

    @Test
    public void bubbleSortTest() {
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	BubbleSort.bubbleSort(intList);
	assertEquals(expIntList, intList);
    }

    public static void bubbleSort(List<Integer> intList) {
	for (int i = 0; i < intList.size(); i++) {
	    for (int j = 0; j < intList.size() - i - 1; j++) {
		int prevValue = intList.get(j);
		int currValue = intList.get(j + 1);
		// The biggest value bubbles to the end of the list
		if (prevValue > currValue) {
		    intList.set(j, currValue);
		    intList.set(j + 1, prevValue);
		}
	    }
	}
    }
}

    2> Quick Sort

package edu.xmu.datastructure.sort.swap;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class QuickSort {

    @Test
    public void quickSortTest() {
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	QuickSort.quickSort(intList, 0, intList.size() - 1);
	assertEquals(expIntList, intList);
    }

    public static void quickSort(List<Integer> intList, int startIndex,
	    int endIndex) {
	if (startIndex < endIndex) {
	    int pivotIndex = splitList(intList, startIndex, endIndex);
	    quickSort(intList, startIndex, pivotIndex - 1);
	    quickSort(intList, pivotIndex + 1, endIndex);
	}
    }

    @Test
    public void splitListTest() {
	List<Integer> expectedIntList = Lists.newArrayList(27, 38, 13, 49, 76,
		97, 65);
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	int newPivotIndex = QuickSort.splitList(intList, 0, 6);
	assertEquals(expectedIntList, intList);
	assertEquals(3, newPivotIndex);
    }

    public static int splitList(List<Integer> intList, int pivotIndex, int high) {
	int pivotValue = intList.get(pivotIndex);
	int low = pivotIndex;

	boolean shouldHighMove = true;
	while (low < high) {
	    if (shouldHighMove) {
		if (intList.get(high) < pivotValue) {
		    int lowValue = intList.get(low);
		    int highValue = intList.get(high);
		    intList.set(low, highValue);
		    intList.set(high, lowValue);
		    low++;
		    shouldHighMove = false;
		} else {
		    shouldHighMove = true;
		    high--;
		}
	    } else {
		if (intList.get(low) > pivotValue) {
		    int lowValue = intList.get(low);
		    int highValue = intList.get(high);
		    intList.set(low, highValue);
		    intList.set(high, lowValue);
		    high--;
		    shouldHighMove = true;
		} else {
		    shouldHighMove = false;
		    low++;
		}
	    }
	}
	if (high != low) {
	    throw new RuntimeException("Defacted Algorithm!");
	}
	intList.set(low, pivotValue);
	return low;
    }
}

 

3. Selection Sort

    1> Simple Selection Sort

package edu.xmu.datastructure.sort.selection;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class SimpleSelectionSort {
    @Test
    public void insertSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);

	SimpleSelectionSort.selectionSort(intList);
	assertEquals(expIntList, intList);
    }

    public static void selectionSort(List<Integer> intList) {
	int minValue;
	int indexToBeSwapped;
	for (int i = 0; i < intList.size(); i++) {
	    minValue = Integer.MAX_VALUE;
	    indexToBeSwapped = 0;

	    for (int j = i; j < intList.size(); j++) {
		int temp = intList.get(j);
		if (minValue > temp) {
		    minValue = temp;
		    indexToBeSwapped = j;
		}
	    }
	    int value = intList.get(i);
	    intList.set(i, minValue);
	    intList.set(indexToBeSwapped, value);
	}
    }
}

      Simple Selection Sort (Extract getMinValueIndex out, make code easier to read)

package edu.xmu.datastructure.sort.selection;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class SimpleSelectionSort {
    @Test
    public void insertSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);

	SimpleSelectionSort.selectionSort(intList);
	assertEquals(expIntList, intList);
    }

    public static void selectionSort(List<Integer> intList) {
	for (int i = 0; i < intList.size(); i++) {
	    int minValueIndex = getMinValueIndex(i, intList);
	    int minValue = intList.get(minValueIndex);

	    int tempValue = intList.get(i);
	    intList.set(i, minValue);
	    intList.set(minValueIndex, tempValue);
	}
    }

    private static int getMinValueIndex(int startIndex, List<Integer> intList) {
	int minValue = Integer.MAX_VALUE;
	int minValueIndex = 0;
	for (int j = startIndex; j < intList.size(); j++) {
	    int temp = intList.get(j);
	    if (minValue > temp) {
		minValue = temp;
		minValueIndex = j;
	    }
	}
	return minValueIndex;
    }
}

    2> Tree Selection Sort (Tournament Sort): It's just a transition selection sort algorithm between "Simple Selection Sort" and "Heap Sort"

package edu.xmu.datastructure.sort.selection;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class TreeSelectionSort {

    @Test
    public void selectionSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);

	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);

	List<Integer> orderedIntList = TreeSelectionSort
		.treeSelectionSort(intList);
	assertEquals(expIntList, orderedIntList);
    }

    public static List<Integer> treeSelectionSort(List<Integer> intList) {

	BinarySelectionTreeNode rootNode = buildTree(intList);
	List<Integer> orderedIntList = Lists.newArrayListWithCapacity(intList
		.size());
	int minValue;
	for (int i = 0; i < intList.size(); i++) {
	    rootNode.reElectMinValue();

	    minValue = rootNode.getValue();
	    orderedIntList.add(minValue);

	    rootNode.removeMinValue(minValue);
	}
	return orderedIntList;
    }

    public static BinarySelectionTreeNode buildTree(List<Integer> intList) {
	List<BinarySelectionTreeNode> leafNodes = Lists
		.newArrayListWithExpectedSize(intList.size());

	for (int value : intList) {
	    BinarySelectionTreeNode leafNode = new BinarySelectionTreeNode();
	    leafNode.setValue(value);
	    leafNodes.add(leafNode);
	}

	List<BinarySelectionTreeNode> rootNode = buildFromNodes(leafNodes);
	return rootNode.get(0);
    }

    private static List<BinarySelectionTreeNode> buildFromNodes(
	    List<BinarySelectionTreeNode> nodes) {
	if (nodes.size() <= 1) {
	    return nodes;
	}

	if (nodes.size() % 2 != 0) {
	    nodes.add(new BinarySelectionTreeNode());
	}
	List<BinarySelectionTreeNode> mergedNodes = Lists
		.newArrayListWithCapacity(nodes.size() / 2);

	for (int i = 0; i < nodes.size(); i += 2) {
	    BinarySelectionTreeNode mergedNode = new BinarySelectionTreeNode();
	    BinarySelectionTreeNode lChildNode = nodes.get(i);
	    BinarySelectionTreeNode rChildNode = nodes.get(i + 1);

	    mergedNode.setlChild(lChildNode);
	    mergedNode.setrChild(rChildNode);
	    mergedNodes.add(mergedNode);
	}
	return buildFromNodes(mergedNodes);
    }

    public static class BinarySelectionTreeNode {
	private int value = Integer.MAX_VALUE;
	private BinarySelectionTreeNode lChild;
	private BinarySelectionTreeNode rChild;

	public void removeMinValue(int minValue) {
	    if (null == lChild && null == rChild) {
		if (minValue == this.value) {
		    this.value = Integer.MAX_VALUE;
		}
	    } else {
		if (this.value == minValue) {
		    this.value = Integer.MAX_VALUE;
		    lChild.removeMinValue(minValue);
		    rChild.removeMinValue(minValue);
		}
	    }
	}

	public int reElectMinValue() {
	    int minValue = Integer.MAX_VALUE;
	    if (null == lChild && null == rChild) {
		minValue = this.value;
	    } else {
		int lMinValue = lChild.reElectMinValue();
		int rMinValue = rChild.reElectMinValue();
		minValue = lMinValue < rMinValue ? lMinValue : rMinValue;
	    }
	    this.value = minValue;
	    return minValue;
	}

	public int getValue() {
	    return value;
	}

	public void setValue(int value) {
	    this.value = value;
	}

	public BinarySelectionTreeNode getlChild() {
	    return lChild;
	}

	public void setlChild(BinarySelectionTreeNode lChild) {
	    this.lChild = lChild;
	}

	public BinarySelectionTreeNode getrChild() {
	    return rChild;
	}

	public void setrChild(BinarySelectionTreeNode rChild) {
	    this.rChild = rChild;
	}

    }
}

    3> Heap Sort

package edu.xmu.datastructure.sort.selection;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class HeapSort {
    @Test
    public void heapSortTest() {
	// 49
	// 38 65
	// 97 76 13 27
	List<Integer> intList = Lists.newArrayList(Integer.MAX_VALUE, 49, 38,
		65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(Integer.MAX_VALUE, 13,
		27, 38, 49, 65, 76, 97);
	HeapSort.heapSort(intList);
	assertEquals(expIntList, intList);
    }

    public static void heapSort(List<Integer> intList) {
	for (int i = intList.size() / 2; i >= 1; i--) {
	    adjustHeap(intList, i, intList.size() - 1);
	}

	for (int i = intList.size() - 1; i >= 1; i--) {
	    int maxValue = intList.get(1);
	    int tailValue = intList.get(i);

	    intList.set(1, tailValue);
	    intList.set(i, maxValue);
	    adjustHeap(intList, 1, i - 1);
	}
    }

    // Max Heap
    private static void adjustHeap(List<Integer> intList, int startIndex,
	    int endIndex) {
	int rootNodeValue = intList.get(startIndex);
	int currentIndex = startIndex;
	for (int i = startIndex * 2; i <= endIndex; i *= 2) {
	    if (i + 1 > endIndex) {
		// For the benefit of obsolete index
		// When we put the max value at the end of array
		// Then [start, end - 1]
		// But here intList.get(i + 1) may unintentionally get the
		// already set as max and thus unreachable
	    } else if (intList.get(i) < intList.get(i + 1)) {
		i += 1;
	    }

	    if (rootNodeValue > intList.get(i)) {
		// rootNode is bigger than its children
		break;
	    }

	    intList.set(currentIndex, intList.get(i));
	    currentIndex = i;
	}
	intList.set(currentIndex, rootNodeValue);
    }
}

 

4. Merge Sort

package edu.xmu.datastructure.sort.merge;

import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;

public class MergeSort {

    @Test
    public void mergeSortTest() {
	List<Integer> intList = Lists.newArrayList(49, 38, 65, 97, 76, 13, 27);
	List<Integer> expIntList = Lists.newArrayList(13, 27, 38, 49, 65, 76,
		97);
	List<Integer> sortedIntList = MergeSort.mergeSort(intList, 0,
		intList.size() - 1);
	assertEquals(expIntList, sortedIntList);
    }

    public static List<Integer> mergeSort(List<Integer> intList,
	    int startIndex, int endIndex) {
	List<Integer> mergedList;
	if (startIndex == endIndex) {
	    mergedList = Lists.newArrayList(intList.get(startIndex));
	} else {
	    int middleIndex = (startIndex + endIndex) / 2;

	    List<Integer> leftList = mergeSort(intList, startIndex, middleIndex);
	    List<Integer> rightList = mergeSort(intList, middleIndex + 1,
		    endIndex);

	    mergedList = mergeSortedList(leftList, rightList);
	}

	return mergedList;
    }

    @Test
    public void mergeListTest() {
	List<Integer> leftList = Lists.newArrayList(1, 3, 5, 7);
	List<Integer> rightList = Lists.newArrayList(0, 2);

	List<Integer> expectedMergedList = Lists.newArrayList(0, 1, 2, 3, 5, 7);
	List<Integer> mergedList = MergeSort.mergeSortedList(leftList,
		rightList);

	assertEquals(expectedMergedList, mergedList);

	leftList = Lists.newArrayList(1, 3, 5, 7);
	rightList = Lists.newArrayList(0, 2, 4, 6, 8, 9);

	expectedMergedList = Lists.newArrayList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
	mergedList = MergeSort.mergeSortedList(leftList, rightList);

	assertEquals(expectedMergedList, mergedList);
    }

    /**
     * Merge two ascending sorted list into one single asc list
     * 
     * @param leftList
     * @param rightList
     * @return
     */
    public static List<Integer> mergeSortedList(List<Integer> leftList,
	    List<Integer> rightList) {
	List<Integer> mergedList = Lists.newArrayList();

	int leftSize = leftList.size();
	int rightSize = rightList.size();
	int leftIndex = 0;
	int rightIndex = 0;
	int leftValue = Integer.MAX_VALUE;
	int rightValue = Integer.MAX_VALUE;

	while (!(leftIndex == leftSize && rightIndex == rightSize)) {
	    if (leftIndex < leftSize) {
		leftValue = leftList.get(leftIndex);
	    } else {
		leftValue = Integer.MAX_VALUE;
	    }
	    if (rightIndex < rightSize) {
		rightValue = rightList.get(rightIndex);
	    } else {
		rightValue = Integer.MAX_VALUE;
	    }

	    if (rightValue < leftValue) {
		mergedList.add(rightValue);
		rightIndex++;
	    } else {
		mergedList.add(leftValue);
		leftIndex++;
	    }
	}

	return mergedList;
    }
}

 

 

 

Reference Links:

1> http://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html

2> "Data Structure(C version)" - Yan, Weimin

你可能感兴趣的:(java,sort)