排序算法
一、 简单排序
1. 冒泡排序

(1)

(2)
a、相邻位置两两交换,直到最大数排好序。
b、对剩下元素重复此步骤。
code:
int temp;
for(int i = arr.length - 1; i > 0; i--)
for( int j = 0; j < i; i++) // 对 i 个元素,比较i - 1 次
if(arr[i] > arr[i + 1]){
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
2. 选择排序

(1)

(2)
a、从队列中选择最小元素与队首元素交换,队首元素现已有序
b、重复步骤a
code:
for(int i = 0; i < arr.length - 1; i++){
int min = i;
for(int j = i+1; j < arr.length; j++){
if(arr[min] > arr[j])
min = j;
}
swap(i, index);
}
3. 插入排序

(1)

(2)
a、部分有序的数列,取出被标记元素,比该元素大的数依次右移。空处插入标记元素。
b、重复上步骤
code:
int i, j, temp;
for( i = 1; i < arr.length; i++){
temp = a[i];
for( j = i; j > 0 && temp < arr[j-1]; j--)
arr[j] = arr[j-1];
arr[j] = temp;
}
二、 高级排序
1.归并排序


(1) (2) (3)
a、两个有序数组合并是简单的。
b、调用递归,将数组分成一半一半。
code:
public void merge(int[] workspace, int lowPtr, int highPtr, int upperBound){
int j = 0;
int lowerBound = lowPtr;
int mid = highPtr - 1;
int n = upperBound - lowPtr + 1;
while(lowPtr <= mid && highPtr <= upperBound)
if(arr[lowPtr] < arr[highPtr])
workspace[j++] = arr[lowPtr++];
else
workspace[j++] = arr[highPtr++];
while(lowPtr <= mid)
workspace[j++] = arr[lowPtr++];
while(highPtr <= upperBound)
workspace[j++] = arr[highPtr++];
for(j = 0; j < n; j++)
arr[lowerBound + j] = workspace[j];
}
public void recMergeSort(int[] workspace, int lowerBound, int upperBound){
if(lowerBound >= upperBound)
return;
int mid = (lowerBound + upperBound) / 2;
recMergeSort(workspace, lowerBound, mid);
recMergeSort(workspace, mid + 1, upperBound);
merge(workspace, lowerBound, mid + 1, upperBound);
}
2. 希尔排序

(1) (2)
a、对增量为N=(3*n + 1)的元素进行排序,N逐步减小直至为1.
b、当N为1时,该算法退化为插入排序。
code:
int inner, outer;
int temp;
int h = 1;
while(h <= length/3)
h = h*3 + 1;
while(h>0){
for(outer = h; outer < length; outer++){
temp = arr[outer];
inner = outer;
while(inner > h-1 && arr[inner-h] >= temp){
arr[inner] = arr[inner-h];
inner -= h;
}
arr[inner] = temp;
}
h = (h-1) / 3;
}
3. 快速排序

a、以数组左右端元素为pivot划分数组
b、递归调用左右子数组
code:
public int partitionIt(int left, int right, int pivot){
int leftPtr = left - 1;
int rightPtr = right;
while(true){
while(leftPtr < right && arr[++leftPtr] < pivot)
;
while(rightPtr > left && arr[--rightPtr] > pivot)
;
if(leftPtr >= rightPtr)
break;
else
swap(leftPtr, rightPtr);
}
swap(leftPtr, right);
return leftPtr;
}
public void quickSort(int left, int right){
if(right <= left)
return;
else{
int pivot = arr[right];
int partion = partitionIt(left, right, pivot);
quickSort(left, partion - 1);
quickSort(partion + 1, right);
}
}
}
4. 堆排序
堆排序分为建堆和堆调整两个过程。
首先描述堆调整过程,这是堆排序的核心。从最后一个非叶子节点开始。判断该节点与其最大子节点值的大小。若该节点值较小,则交换该节点与最大孩子节点。往下一直重复此操作,直至孩子节点<长度len为止。
对上一个非叶子节点重复操作,直至到达根节点为止。
public static void adjustHeap(int[] arr, int pos, int len){
int child;
while(2*pos + 1 <= len){ // 判断是否到达最下层
child = 2*pos + 1;
if(child < len && arr[child] < arr[child+1]) // 寻找最大子节点
child++;
if(arr[pos] < arr[child])
swap(arr, pos, child); // 若父节点较小,交换
else
break;
pos = child; // 重置标志,往下重复到最下层
}
}
public static void heapSort(int[] arr){
int len = arr.length;
for(int i = len/2 - 1; i >= 0; i--) // 从最后一个非叶子节点开始,把堆调整为大根堆
adjustHeap(arr, i, len-1); //adjustHeap只调整一趟
for(int i = len-1; i >= 0; i--){
swap(arr, 0, i);
adjustHeap(arr, 0, i-1);
}
}

浙公网安备 33010602011771号