排序算法动手研究
2016-12-16 22:02
246 查看
这段时间研究了一下排序算法,动手的感觉真好,学习算法也提高了兴趣。
快速排序
堆排序
插入排序
归并排序
非递归的归并排序
冒泡排序
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;
}
}
}
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;
}
}
}
相关文章推荐
- 关于JAVA的几种排序算法研究
- 排序算法的稳定性研究
- 自己动手实现数据结构——排序算法2 (希尔、快速、堆)(C++实现)
- 搜索引擎算法研究专题一:基于页面分块的搜索引擎排序算法改进
- 搜索结果排序算法的研究
- 【算法研究】排序算法
- 常见排序算法的研究与实现
- 排序算法研究
- 自己动手实现数据结构——排序算法1(冒泡、插入、归并、简单选择)(C++实现)
- 算法复杂度,及三种主要排序算法的研究
- 关于基本排序算法的简单研究总结(java 实现)
- 搜索结果排序算法的研究(张天/ccl.pku.edu.cn)
- 程序员必须知道和动手实现的7种排序算法 .
- 排序算法的稳定性研究
- Android开发周报:反编译对抗研究、动手制作智能镜子
- 排序算法的研究
- Android开发周报:反编译对抗研究、动手制作智能镜子
- 深入剖析排序算法(二)------直接插入排序的研究及改进
- 排序算法研究
- 搜索引擎算法研究专题一:基于页面分块的搜索引擎排序算法改进