您的位置:首页 > 其它

排序算法动手研究

2016-12-16 22:02 246 查看
这段时间研究了一下排序算法,动手的感觉真好,学习算法也提高了兴趣。

public abstract class MySort {
public int[] array;

public abstract void sort();

public MySort(int[] array) {
this.array = array;
}

public void printArray(String desp, int[] array){
System.out.println(desp);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}

public void exChangeElement(int[] array,int index,int largest){
int value = array[index];
array[index] = array[largest];
array[largest] = value;
}

public static void main(String[] args) {
int[] array = new int[]{9,8,2,53,23,2,321,232,467,54,78,54,34,3,998};
//        MySort algo = new HeapSort(array);
//        MySort algo = new InsertSort(array);
//        MySort algo = new MergeSort(array);
//        MySort algo = new MergeSortNonRecursive(array);
MySort algo = new QuickSort(array);
algo.printArray("original:",array);
algo.sort();
algo.printArray("after:",array);
}

}


快速排序

public class QuickSort extends MySort {

public QuickSort(int[] array) {
super(array);
}

@Override
public void sort() {
quickSort(array, 0, array.length - 1);
}

private void quickSort(int[] array, int start, int end) {
if (array == null || end <= start) {
return;
}
int lastChangePos = splitCompare(array, start, end);
if (lastChangePos == start) {
//后面元素都比基准元素大
quickSort(array, lastChangePos + 1, end);
} else if (lastChangePos == end) {
//后面元素都比基准元素小
quickSort(array, start, lastChangePos - 1);
} else {
//基准元素处于中间
quickSort(array, start, lastChangePos - 1);
quickSort(array, lastChangePos + 1, end);
}
}

private int splitCompare(int[] array, int start, int end) {
int quickElement = array[end];

int exChangePos = start - 1;
for (int currPos = start; currPos < end; currPos++) {
if (array[currPos] < quickElement) {
exChangePos++;//理解这个是关键:指示的是最近的一个小于基准元素值的索引
if (exChangePos != currPos) {
exChangeElement(array, exChangePos, currPos);
}
}
}

if (exChangePos + 1 != end) {
exChangeElement(array, exChangePos + 1, end);
}

printArray(String.format("after splitCompare:(from %d to %d)", start, end), array);
return exChangePos + 1;
}
}


堆排序

public class HeapSort extends MySort {
public HeapSort(int[] array) {
super(array);
}

@Override
public void sort() {
if(array == null && array.length <= 1){
return;
}

buildMaxHeap(array);
printArray("after buildMaxHeap:",array);
for (int size = array.length - 1; size >=1 ; size--) {
moveMaxElement(array,0,size);//移走最大值元素
printArray(size + " after moveMaxElement:",array);
adjustHeap(array,0,size);//从0号开始
printArray(size + " after adjustHeap:",array);
}
}

private void buildMaxHeap(int[] array) {
if(array == null && array.length <= 1){
return;
}
//从最后一个非叶子节点元素开始排序
for (int adjustIndex = array.length/2 ; adjustIndex >= 0; adjustIndex--) {
adjustHeap(array,adjustIndex,array.length);
}
}

private void moveMaxElement(int[] array, int fisrtIndex, int lastIndex) {
exChangeElement(array,fisrtIndex,lastIndex);
}

private void adjustHeap(int[] array, int adjustIndex, int heapSize) {
int largest = adjustIndex;
int left = adjustIndex * 2 + 1;//左子元素不一定存在
int right = adjustIndex * 2 + 2;//右子元素不一定存在
if(left < heapSize && array[left] > array[largest]){
largest = left;
}
if(right < heapSize && array[right] > array[largest]){
largest = right;
}
if(largest != adjustIndex){
exChangeElement(array,adjustIndex,largest);//父子交换
adjustHeap(array,largest,heapSize);//递归的建立大顶堆
}
}

}


插入排序

public class InsertSort extends MySort {

public InsertSort(int[] array) {
super(array);
}

@Override
public void sort() {
for (int cur = 0; cur < array.length; cur++) {
insertSortedArray(array,cur,array[cur]);
}
}

private void insertSortedArray(int[] array, int sortedSize, int value) {
if(sortedSize == 0){
array[0] = value;
}else{
int cur = sortedSize - 1;
while(cur >= 0 && array[cur] > value){
array[cur+1] = array[cur];
cur--;
}
array[cur+1] = value;
}
}
}


归并排序

public class MergeSort extends MySort {

public MergeSort(int[] array) {
super(array);
}

@Override
public void sort() {
mergeSort(array, 0, array.length - 1);
}

private void mergeSort(int[] array, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
mergeSort(array, low, mid);//左侧继续merge排序
mergeSort(array, mid + 1, high);//右侧继续merge排序
merge(array, low, mid, high);//左右侧整合,这个是核心
}
}

private void merge(int[] array, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int leftIndex = low;
int rightIndex = mid + 1;
int tempIndex = 0;
while (leftIndex <= mid && rightIndex <= high) {
if (array[leftIndex] < array[rightIndex]) {
temp[tempIndex++] = array[leftIndex++];
} else {
temp[tempIndex++] = array[rightIndex++];
}
}

//左侧有多余的
while (leftIndex <= mid) {
temp[tempIndex++] = array[leftIndex++];
}

//右侧有多余的
while (rightIndex <= high) {
temp[tempIndex++] = array[rightIndex++];
}

//将临时排序好的何如到原来的数组当中
for (int i = 0; i < temp.length; i++) {
array[low + i] = temp[i];
}
}
}


非递归的归并排序

public class MergeSortNonRecursive extends MySort {

public MergeSortNonRecursive(int[] array) {
super(array);
}

@Override
public void sort() {
nrMergeSort(array, array.length);
}

private void nrMergeSort(int[] array, int size) {
//直接申请n长度的数组空间
int[] temp = new int[size];

int stepLength = 1;
//以2的次幂为步长进行归并排序
while (stepLength < size) {
//每次合并到temp中时,都需要会写到array中,然后进行下一轮的合并
mergeSort(array, temp, stepLength, size);
stepLength *= 2;
}
}

//循环建立以2*stepLength为长度的子数组进行归并排序
private void mergeSort(int[] array, int[] temp, int stepLength, int size) {
final int SUB_ARRAY_SIZE = 2 * stepLength;
int i = 0;
while (i + SUB_ARRAY_SIZE <= size - 1) {
int subArrayBegin = i;
int subArrayMiddle = i + stepLength - 1;
int subArrayEnd = i + 2 * stepLength - 1;
merge(array, temp, subArrayBegin, subArrayMiddle, subArrayEnd);
i += SUB_ARRAY_SIZE;
}
//剩下的元素长度大于一个stepLength,但是小于2*stepLength,还需要进行一次归并
if (size - i + 1 > stepLength) {
merge(array, temp, i, i + stepLength - 1, size - 1);
}else{
//剩下的元素不足一个stepLength
for (int j = i; j < size; j++) {
temp[j] = array[j];
}
}

//回写到原来的数组当中
for (int s = 0; s < size; s++) {
array[s] = temp[s];
}
}

//核心:merge一段子数组
private void merge(int[] array, int[] temp, int begin, int mid, int end) {
int array1Index = begin;
int array2Index = mid + 1;
int pos;
for (pos = array1Index; array1Index <= mid && array2Index <= end; pos++) {
if(array[array1Index] < array[array2Index]){
temp[pos] = array[array1Index++];
}else{
temp[pos] = array[array2Index++];
}
}
if(array1Index <= mid){
for (int h = 0; h <= mid - array1Index; h++) {
temp[pos + h] = array[array1Index + h];
}
}else{
for (int h = 0; h <= end - array2Index; h++) {
temp[pos + h] = array[array2Index + h];
}
}
}
}

冒泡排序

public class BubbleSort extends MySort {
public BubbleSort(int[] array) {
super(array);
}

@Override
public void sort() {
for (int cur = 0; cur < array.length - 1; cur++) {
for (int next = 0; next < array.length - 1 - cur; next++) {
if(array[next] > array[next+1]){
exChangeElement(array,next,next+1);
}
}
}
}
}

public class MarkedBubbleSort extends MySort {
public MarkedBubbleSort(int[] array) {
super(array);
}

@Override
public void sort() {
//设置一个标志位,记录上次交换的位置,后面的为交换的元素则代表了已经排序好了
int lastExchangePos = array.length - 1;
for (int cur = 0; cur < array.length - 1; cur++) {

int exChangePos = lastExchangePos;
for (int next = 0; next < lastExchangePos; next++) {
if(array[next] > array[next+1]){
exChangeElement(array,next,next+1);
exChangePos = next;
}
}

lastExchangePos = exChangePos;
}
}
}

public class MaxMinBubbleSort extends MySort {
public MaxMinBubbleSort(int[] array) {
super(array);
}

@Override
public void sort() {
int low = 0;
int high = array.length - 1;
while (low < high) {
for (int j = low; j < high; j++) {//正向冒泡
if (array[j] > array[j + 1]) {
exChangeElement(array, j, j + 1);
}
}
--high;
for (int j = high; j > low; j--) {//反向冒泡
if (array[j] < array[j - 1]) {
exChangeElement(array, j, j - 1);
}
}
++low;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法 算法