基本排序
时间复杂度都是O(n^2)
冒泡排序
public static int[] bubbleSort(int[] array) {
// Write your code here.
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
return array;
}
插入排序
public static int[] insertionSort(int[] array) {
// Write your code here.
for (int i = 1; i < array.length; i++) {
for (int j = 0; j < i; j++) {
if (array[i] < array[j]) {
int temp = array[i];
for (int k = i-1; k >= j; k--) {
array[k+1] = array[k];
}
array[j] = temp;
break;
}
}
}
return array;
}
选择排序
public static int[] selectionSort(int[] array) {
// Write your code here.
for (int i = 0; i < array.length; i++) {
int min = array[i];
int mini = i;
for (int j = i+1; j < array.length; j++) {
if (array[j] < min) {
min = array[j];
mini = j;
}
}
swap(array, i, mini);
}
return array;
}
进阶排序
快速排序
时间复杂度O(nlogn),对于相对有序的数组可能会退化到O(n^2)
public static int[] quickSort(int[] array) {
// Write your code here.
qSort(array, 0, array.length - 1);
return array;
}
public static void qSort(int[] array, int left, int right) {
if (left < right) {
int pivot = partition(array, left, right);
qSort(array, left, pivot - 1);
qSort(array, pivot + 1, right);
}
}
public static int partition(int[] array, int left, int right) {
int pivot = (right - left) / 2 + left;
while (left < right) {
while (array[left] <= array[pivot] && left < pivot) {
left++;
}
swap(array, left, pivot);
pivot = left;
while (array[right] >= array[pivot] && pivot < right) {
right--;
}
swap(array, right, pivot);
pivot = right;
}
return pivot;
}
快排变形寻找第K大的数
public int findKth(int[] a, int n, int K) {
// write code here
qsort(a, 0, n-1, K);
return a[K - 1];
}
public static void qsort(int[] a, int start, int end, int k) {
if (start < end) {
int pivot = partition(a, start, end);
if (pivot == k - 1) {
return;
}
if (pivot > k - 1) {
qsort(a, start, pivot - 1, k);
}
if (pivot < k - 1) {
qsort(a, pivot + 1, end, k);
}
}
}
public static int partition(int[] a, int start, int end) {
int v = a[start];
int index = start + 1;
for (int i = index; i <= end; i++) {
if (a[i] > v) {
swap(a, i, index);
index++;
}
}
swap(a, start, index - 1);
return index - 1;
}
归并排序
时间复杂度O(nlogn)
public static int[] mergeSort(int[] array) {
// Write your code here.
mSort(array, 0, array.length - 1);
return array;
}
public static void mSort(int[] array, int left, int right) {
int mid = (right - left) / 2 + left;
if (left < right) {
// attention: must be mid + 1
mSort(array, left, mid);
mSort(array, mid + 1, right);
merge(array, left, mid, right);
}
}
public static void merge(int[] array, int left, int mid, int right) {
int[] tempArray = new int[right - left + 1];
int index = 0;
int leftp = left;
int rightp = mid + 1;
while (leftp <= mid && rightp <= right) {
if (array[leftp] <= array[rightp]) {
tempArray[index++] = array[leftp++];
}
if (array[leftp] > array[rightp]) {
tempArray[index++] = array[rightp++];
}
}
while (leftp <= mid) {
tempArray[index++] = array[leftp++];
}
while (rightp <= right) {
tempArray[index++] = array[rightp++];
}
System.arraycopy(tempArray, 0, array, left, right-left+1);
}
堆排序
堆排序时间复杂度O(nlogn)
堆排序首先要建堆,从小到大排序就要建立大根堆,然后进行下沉操作
public static int[] heapSort(int[] array) {
// Write your code here.
buildMaxHeap(array);
for (int endIdx = array.length - 1; endIdx > 0; endIdx--) {
swap(array, 0, endIdx);
siftDown(0, endIdx - 1, array);
}
return array;
}
public static void buildMaxHeap(int[] array) {
int firstParentIdx = (array.length - 2) / 2;
for (int currentIdx = firstParentIdx; currentIdx >=0; currentIdx--) {
siftDown(currentIdx, array.length - 1, array);
}
}
public static void siftDown(int currentIdx, int endIdx, int[] array) {
int childOne = currentIdx * 2 + 1;
while (childOne <= endIdx) {
int childTwo = childOne + 1 <= endIdx ? childOne + 1 : -1;
int swapToIdx = childOne;
if (childTwo != -1 && array[childTwo] > array[childOne]) {
swapToIdx = childTwo;
}
if (array[swapToIdx] > array[currentIdx]) {
swap(array, swapToIdx, currentIdx);
currentIdx = swapToIdx;
childOne = currentIdx * 2 + 1;
} else {
return;
}
}
}
堆还有一个上浮操作,主要用在插入一个节点的时候,堆插入节点都为最后一个位置。堆删除一个节点只能删除第一个节点。
public void siftUp(int currentIdx, List<Integer> heap) {
// Write your code here.
int parentIndex = (currentIdx - 1) / 2;
while (currentIdx > 0 && heap.get(currentIdx) < heap.get(parentIndex)) {
swap(currentIdx, parentIndex, heap);
currentIdx = parentIndex;
parentIndex = (currentIdx - 1) / 2;
}
}