排序算法
选择排序(冒泡法):
首先遍历数组 找出n个数据中最小的 放到第一位, 然后从剩下的n-1个元素中找出最小的 放到第二位, 一次类推 直到排好序为止
Java代码:
public static void selectionSort(int[] arr)
{
int smallIndex; // index of smallest element in the sublist
int pass, j, n = arr.length;
int temp;
// pass has the range 0 to n-2
for (pass = 0; pass < n-1; pass++)
{
// scan the sublist starting at index pass
smallIndex = pass;
// j traverses the sublist arr[pass+1] to arr[n-1]
for (j = pass+1; j < n; j++)
// if smaller element found, assign smallIndex
// to that position
if (arr[j] < arr[smallIndex])
smallIndex = j;
// swap the next smallest element into arr[pass]
temp = arr[pass];
arr[pass] = arr[smallIndex];
arr[smallIndex] = temp;
}
}
泛型版本:(基本上跟上面是相似的)
public static <T extends Comparable<? super T>>
void selectionSort(T[] arr)
{
int smallIndex; // index of smallest element in the sublist
int pass, j, n = arr.length;
T temp;
// pass has the range 0 to n-2
for (pass = 0; pass < n-1; pass++)
{
// scan the sublist starting at index pass
smallIndex = pass;
// j traverses the sublist arr[pass+1] to arr[n-1]
for (j = pass+1; j < n; j++)
// if smaller element found, assign smallIndex
// to that position
if (arr[j].compareTo(arr[smallIndex]) < 0)
smallIndex = j;
// swap the next smallest element into arr[pass]
temp = arr[pass];
arr[pass] = arr[smallIndex];
arr[smallIndex] = temp;
}
}
插入排序:
基于一个已经排好序的数组(数组长度为1时), 然后找到当前元素在改数组中的位置, 之后的元素顺次后推即可
(插入排序是最好的二次算法,对小数组来说十分有效)
public static <T extends Comparable<? super T>>
void insertionSort(T[] arr)
{
int i, j, n = arr.length;
T target;
// place element at index i into the sublist
// from index 0 to i-1 where 1 <= i < n,
// so it is in the correct position
for (i = 1; i < n; i++)
{
// index j scans down list from index i looking for
// correct position to locate target. assigns it to
// v at index j
j = i;
target = arr[i];
// locate insertion point by scanning downward as long
// as target < arr[j] and we have not encountered the
// beginning of the array
while (j > 0 && target.compareTo(arr[j-1]) < 0)
{
// shift elements up list to make room for insertion
arr[j] = arr[j-1];
j--;
}
// the location is found; insert target
arr[j] = target;
}
}
归并排序:
通过递归 将一个大的数组分成2个小的数组 若小的两个数组已经排好序 则按顺序将这两个小的数组中的元素一次放回到原数组当中
具体见下图
public static <T extends Comparable<? super T>>
void sort(T[] arr)
{
// create a temporary array to store partitioned elements
T[] tempArr = (T[])arr.clone();
// call mergesort with arrays arr and tempArr along with
// the index range
msort(arr, tempArr, 0, arr.length);
}
private static void
msort(Object[] arr, Object[] tempArr, int first, int last)
{
// if the sublist has more than 1 element continue
if (first + 1 < last)
{
// for sublists of size 2 or more, call msort()
// for the left and right sublists and then
// merge the sorted sublists using merge()
int midpt = (last + first) / 2;
msort(arr, tempArr,first, midpt);
msort(arr, tempArr, midpt, last);
// if list is already sorted, just copy from src to
// dest. this is an optimization that results in faster
// sorts for nearly ordered lists.
if (((Comparable)arr[midpt-1]).compareTo(arr[midpt]) <= 0)
return;
// the elements in the ranges [first,mid) and [mid,last) are
// ordered. merge the ordered sublists into
// an ordered sequence in the range [first,last) using
// the temporary array
int indexA, indexB, indexC;
// set indexA to scan sublist A (index range [first,mid)
// and indexB to scan sublist B (index range [mid, last)
indexA = first;
indexB = midpt;
indexC = first;
// while both sublists are not exhausted, compare arr[indexA] and
// arr[indexB]; copy the smaller to tempArr
while (indexA < midpt && indexB < last)
{
if (((Comparable)arr[indexA]).compareTo(arr[indexB]) < 0)
{
tempArr[indexC] = arr[indexA]; // copy element to tempArr
indexA++; // increment indexA
}
else
{
tempArr[indexC] = arr[indexB]; // copy element to tempArr
indexB++; // increment indexB
}
// increment indexC
indexC++;
}
// copy the tail of the sublist that is not exhausted
while (indexA < midpt)
{
tempArr[indexC] = arr[indexA]; // copy element to tempArr
indexA++;
indexC++;
}
while (indexB < last)
{
tempArr[indexC] = arr[indexB]; // copy element to tempArr
indexB++;
indexC++;
}
// copy elements from temporary array to original array
for (int i = first; i < last; i++)
arr[i] = tempArr[i];
}
}
快速排序:
数据比较多时 效率比较高 时间效率为O(log2n)
pivotIndex函数的作用是将所有比基数小的数放到数组的前一部分, 比基数大的数放到数组的后半部分, 并返回基数的索引
对前后半部分分别递归调用即可完成排序(图中黑色的为基数)
public static <T extends Comparable<? super T>>
void quicksort(T[] arr)
{
qsort(arr, 0, arr.length);
}
private static <T extends Comparable<? super T>>
void qsort(T[] arr, int first, int last)
{
// index of the pivot
int pivotLoc;
// temp used for an exchange when [first,last) has
// two elements
T temp;
// if the range is not at least two elements, return
if (last - first <= 1)
return;
// if sublist has two elements, compare v[first] and
// v[last-1] and exchange if necessary
else if (last - first == 2)
{
if (arr[last-1].compareTo(arr[first]) < 0)
{
temp = arr[last-1];
arr[last-1] = arr[first];
arr[first] = temp;
}
return;
}
else
{
pivotLoc = pivotIndex(arr, first, last);
// make the recursive call
qsort(arr, first, pivotLoc);
// make the recursive call
qsort(arr, pivotLoc +1, last);
}
}
public static <T extends Comparable<? super T>>
int pivotIndex(T[] arr, int first, int last)
{
// index for the midpoint of [first,last) and the
// indices that scan the index range in tandem
int mid, scanUp, scanDown;
// pivot value and object used for exchanges
T pivot, temp;
if (first == last)
// empty sublist
return last;
else if (first == last-1)
// 1-element sublist
return first;
else
{
mid = (last + first)/2;
pivot = arr[mid];
// exchange the pivot and the low end of the range
// and initialize the indices scanUp and scanDown.
arr[mid] = arr[first];
arr[first] = pivot;
scanUp = first + 1;
scanDown = last - 1;
// manage the indices to locate elements that are in
// the wrong sublist; stop when scanDown <= scanUp
for(;;)
{
// move up the lower sublist; continue so long as scanUp is
// less than or equal to scanDown and the array value is
// less than pivot
while (scanUp <= scanDown &&
arr[scanUp].compareTo(pivot) < 0)
scanUp++;
// move down the upper sublist so long as the array value is
// greater than the pivot
while (pivot.compareTo(arr[scanDown]) < 0)
scanDown--;
// if indices are not in their sublists, partition complete
if (scanUp >= scanDown)
break;
// indices are still in their sublists and identify
// two elements in wrong sublists. exchange
temp = arr[scanUp];
arr[scanUp] = arr[scanDown];
arr[scanDown] = temp;
scanUp++;
scanDown--;
}
// copy pivot to index (scanDown) that partitions sublists
// and return scanDown
arr[first] = arr[scanDown];
arr[scanDown] = pivot;
return scanDown;
}
}