说明:
1.养成面向接口编程和代码的规范性的习惯;
2.开始写排序算法以最简单的整型为例,并且默认是从小到大排序;
3.必要时用英文注释,语句可能不通顺,望见谅。
定义排序接口
interface Sortable{
public void sort(int[] array);
public void sort(int[] array, int fromIndex, int toExclusiveIndex);
//public void sort(Comparable[] array);
//public void sort(Comparable[] array, int fromIndex, int toExclusiveIndex);
}
注意接口的命名和变量的命名。
开始实现接口之前说明几点:
1.代码中SortUtil类是非常简单的排序工具类,功能有检查排序时的边界值和交换两个元素;
2.排序抽象类目前主要功能是实现排序前检查参数和边界值越界。
(零)排序抽象类
abstract class AbstractSort implements Sortable{
protected int len = 0;
/*
* template design implement and subclass implements real sort
*/
public void sort(int[] array){
if(array == null || (len = array.length) == 0){
throw new IllegalArgumentException("array is not allow null");
}
// this is subclass implement
sort(array, 0, len);
}
/*
* part implement sort and only check arguments
* because all subclass must check the same arguments
* I think only one check part put on superclass so that can
* maintenance code easy.
*/
public void sort(int[] array, int fromIndex, int toExclusiveIndex){
/*if(array == null || (len = array.length) <= 1)
return ;*/
SortUtil.checkArg(array);
SortUtil.checkRangeForSort(len, fromIndex, toExclusiveIndex);
// really array sort is not implement
// ...
}
public int getLen(){return len;}
}
主函数和用例测试:
package com.zhang.csdn;
import java.util.*;
public class SortTest {
/**@author pizi
* @param @param args
* @return void
*/
public static void main(String[] args) {
String packageName = "com.zhang.csdn.";
String[] sortMethodArray = {"BubbleSort", "MergeSort", "SelectSort", "InsertSort", "QuickSort","HeapSort","ShellSort"};
List<Sortable> sortList = new ArrayList<Sortable>();
//the use cases try to illust as much as possible
int[] src = {2,1,5,1,3,1,7,5,4};
//int[] src = {1};
//int[] src = {};
//int[] src = {1,2,3,4,5};
//int[] src = {1,1,1,1,2};
//int[] src = {5,4,3,2,1};
try{
for(String sortMethodStr : sortMethodArray){
Sortable st =(Sortable)Class.forName(packageName + sortMethodStr).newInstance();
sortList.add(st);
}
}catch(Exception e){
e.printStackTrace();
}
for(Sortable sortMethod : sortList){
int[] target = Arrays.copyOf(src, src.length);
sortMethod.sort(target);
SortUtil.printSortedArray(target, sortMethod);
}
}
}
(一)冒泡排序算法实现(未用抽象类)
class BubbleSort implements Sortable{
@Override
public void sort(int[] array) {
int len = 0;
if(array == null || (len = array.length) == 0){
throw new IllegalArgumentException("array is not allow null");
}
sort(array, 0, len);
}
@Override
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
SortUtil.checkArg(array);
SortUtil.checkRangeForSort(array.length, fromIndex, toExclusiveIndex);
for(int first = toExclusiveIndex - 1; first >= fromIndex; first--){
bubble(array, fromIndex, first);
}
}
/**@author pizi
* from fromIndex to first find the max element and then insert first position
* first is the bubble begin and bubble array has sorted
* @param array
* @param fromIndex
* @param first
* @return void
*/
private void bubble(int[] array, int fromIndex, int first){
for(int i = fromIndex; i < first; i++){
if(array[i+1] < array[i]){
SortUtil.swap(array, i, i+1);
}
}
}
}
(二)归并排序算法实现
class MergeSort extends AbstractSort implements Sortable{
private int[] mergedArray;
/*
* this makes someone confuse that because maybe
* someone does not know superclass invoke subclass
* method sort(int[] ,int ,int)
*/
public void sort(int[] array) {
super.sort(array);
}
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
super.sort(array, fromIndex, toExclusiveIndex);//check argument but not sort
int len = getLen();
this.allocateMergedArray(len);
sort0(array, fromIndex, toExclusiveIndex - 1);
}
private void allocateMergedArray(int len){
mergedArray = new int[len];// first allocate a new space to store temp element
for(int i = 0; i < len; i++){
mergedArray[i] = 0;
}
}
private void sort0(int[] array, int fromIndex, int toIndex){
if(fromIndex < toIndex){
int midIndex = (fromIndex + toIndex) >> 1;
sort0(array, fromIndex, midIndex);
sort0(array, midIndex + 1, toIndex);
merge(array, fromIndex, midIndex, toIndex);
}
}
/**@author pizi
* @param src
* @param leftBegin
* @param leftEnd
* @param rightEnd
* @return void
* src[leftBegin] to src[leftEnd] has sorted and set part1
* src[leftEnd+1] to src[rightEnd] has sorted and set part2
* merge part1 and part2 to a sorted part
*
*/
private void merge(int[] src, int leftBegin, int leftEnd, int rightEnd){
int rightBegin = leftEnd + 1;
int i = leftBegin;
int j = rightBegin;
int k = 0;// mergedArray index
while(i <= leftEnd || j <= rightEnd){
boolean leftUse = (j > rightEnd)||(i <= leftEnd && (src[i] < src[j]));
if(leftUse){
mergedArray[k++] = src[i++];
}else{
mergedArray[k++] = src[j++];
}
}
// current len equal to k-1
// copy mergedArray to src
for(int srcIndex = rightEnd, mergeIndex = k -1; (mergeIndex >= 0) && (srcIndex >= leftBegin);){
src[srcIndex--] = mergedArray[mergeIndex --];
}
}
}
(三)选择排序算法实现
class SelectSort extends AbstractSort implements Sortable{
@Override
public void sort(int[] array) {
super.sort(array);
}
@Override
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
super.sort(array, fromIndex, toExclusiveIndex);
for(int i = toExclusiveIndex - 1; i >= fromIndex; i--){
int position = this.getPosition(array, fromIndex, i);
SortUtil.swap(array, i, position);
}
}
/**@author pizi
* @param array
* @param low
* @param high
* @return int
* return the max element position from array[low] to array[high]
*/
private int getPosition(int[] array, int low, int high){
int position = low;
for(int i = low; i <=high; i++){
if(array[position] < array[i]){
position = i;
}
}
return position;
}
}
(四)插入排序算法实现
class InsertSort extends AbstractSort implements Sortable{
@Override
public void sort(int[] array) {
super.sort(array);
}
@Override
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
//SortUtil.checkArg(array);
//SortUtil.checkRangeForSort(array.length, fromIndex, toExclusiveIndex);
// check arguments
super.sort(array, fromIndex, toExclusiveIndex);
for(int i = fromIndex, toIndex = toExclusiveIndex - 1; i < toIndex; i++){
this.insert(array, fromIndex, i);
}
}
/**@author pizi
* @param array
* @param low
* @param high
* @return void
* array[low] to array[high] has sorted now insert array[high+1]
*/
private void insert(int[] array, int low, int high){
for(int i = high; i >= low && (array[i] > array[i+1]); i--){
SortUtil.swap(array, i, i+1);
}
}
}
(五)快速排序算法实现
class QuickSort extends AbstractSort implements Sortable{
//// random can produce random the position of pivot
private Random random = new Random();
@Override
public void sort(int[] array) {
super.sort(array);
}
@Override
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
//SortUtil.checkArg(array);
//SortUtil.checkRangeForSort(array.length, fromIndex, toExclusiveIndex);
super.sort(array, fromIndex, toExclusiveIndex);
this.sort0(array, fromIndex, toExclusiveIndex - 1);
}
private void sort0(int[] array, int fromIndex, int toIndex){
if(toIndex > fromIndex){
int pivotPos = partition(array, fromIndex, toIndex);
this.sort0(array, fromIndex, pivotPos - 1);
this.sort0(array, pivotPos + 1, toIndex);
}
}
/**@author pizi
* @param array
* @param fromIndex
* @param toIndex
* @return int
* from fromIndex to toIndex find pivot and part array
* to two parts ,(...left ,pivot, right...)
* return the pivot final position when array is sorted
*/
private int partition(int[] array, int fromIndex, int toIndex){
int pivotPosition = fromIndex + random.nextInt(toIndex - fromIndex + 1);
int pivot = array[pivotPosition];
// i point left first more than the pivot
int i = fromIndex;
// j current position allow insert element and
// point right first less than the pivot
int j = toIndex;
array[pivotPosition] = array[j];
while(i < j){
while(i < j && array[i] <= pivot) {i++;}
array[j] = array[i];
while(i < j && array[j] >= pivot) {j--;}
array[i] = array[j];
}
// current i equal to j and insert the pivot
// element because is allowed
array[j] = pivot;
return j;
}
}
(六)堆排序算法实现
class HeapSort extends AbstractSort implements Sortable{
// heap[0] not store element and valid index from 1 to capacity
// heap is fixed by capacity element
private int[] heap;
private int capacity;// the capacity of heap equal to K
private int size;// current real size of heap
@Override
public void sort(int[] array) {
super.sort(array);
}
@Override
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
super.sort(array, fromIndex, toExclusiveIndex);
if(this.getLen() <= 1) return;
this.allocArray(this.getLen());
this.createHeap(array, fromIndex, toExclusiveIndex);
// heap copy to src array
for(int i = fromIndex; i < toExclusiveIndex; i++){
array[i] = this.delete();
}
}
// heap[1] ~ heap[size] are valid
// always check index bound
// heap[child] >= heap[parent]
private void upHeap(){
int child = size;// child node
int parent = size >> 1;// the parent of child
while(parent > 0 && (heap[child] < heap[parent])){
SortUtil.swap(heap, child, parent);
child = parent;
parent = parent >> 1;
}
}
// heap[1] ~ heap[size] are valid
// always check index bound
// heap[child] >= heap[parent]
private void downHeap(){
int parent = 1;// parent node
int child = 2*parent;// always point to the smallest child
int anotherChild = child + 1;// another child
if((anotherChild <= size) && (heap[child] > heap[anotherChild])){
child = anotherChild;
}
while(child <= size && (heap[child] < heap[parent])){
SortUtil.swap(heap, child, parent);
parent = child;
child = 2*parent;
anotherChild = child + 1;
if((anotherChild <= size) && (heap[child] > heap[anotherChild])){
child = anotherChild;
}
}
}
// K>= 2
private void allocArray(int K){
heap = new int[K + 1];
for(int i = 0; i <= K; i++){
heap[i] = 0;
}
capacity = K;// top K min heap
size = 0;
}
// createHeap
private void createHeap(int[] array, int fromIndex, int toExclusiveIndex){
for(int i = fromIndex; i < toExclusiveIndex; i++){
this.insert(array[i]);
}
}
// size <= capacity
private void insert(int element){
if(size > capacity){
throw new IllegalStateException();
}
if(size < capacity){
insertNotFull(element);
}
if(size == capacity){
this.insertFullHeap(element);
}
}
private void insertFullHeap(int element){
throw new UnsupportedOperationException();
}
private void insertNotFull(int element){
heap[++size] = element;// the end heap insert element
upHeap();// then upHeap to satisfy the heap quality
}
private int delete(){
if(size <= 0){
throw new NoSuchElementException();
}
int topElement = heap[1];
heap[1] = heap[size--];
// heap[size] = null;
downHeap();
return topElement;
}
}
(七)希尔排序算法实现
class ShellSort extends AbstractSort implements Sortable {
protected int count = 0;/*real count of array needs to sort*/
protected int offset = 0;/*from offset index element begin */
protected int end = 0;/*end of index */
@Override
public void sort(int[] array) {
super.sort(array);
}
@Override
public void sort(int[] array, int fromIndex, int toExclusiveIndex) {
super.sort(array, fromIndex, toExclusiveIndex);/*initial argument*/
count = toExclusiveIndex - fromIndex;
offset = fromIndex;
end = toExclusiveIndex;
int[] gaps = {5,3,2,1};
for (int gap : gaps) {
for (int i = offset + gap; i < end; i++) {
int j = i;
int temp = array[j];
while ( (hasPreviousIndex(j, gap) &&
(array[previousIndex(j, gap)] > array[j])) ) {
SortUtil.swap(array, j, previousIndex(j, gap));
j = previousIndex(j, gap);
}
array[j] = temp;
}
}
}
private boolean hasPreviousIndex(int currentIndex, int gap) {
return (currentIndex - gap) >= offset;
}
private int previousIndex(int currentIndex, int gap) {
return currentIndex - gap;
}
}