排序算法
排序算法模板
public class Example {
public static void sort(Comparable[] a){
}
public static boolean less(Comparable v, Comparable w){
//comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
return v.compareTo(w)<0;
}
public static void exch(Comparable[] a,int i ,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
//打印数组
public static void show(Comparable[] a){
for (Comparable comparable : a) {
System.out.print(comparable + " ");
}
System.out.println();
}
//判断是否是有序的
public static boolean isSorted(Comparable[] a){
for (int i = 0; i < a.length-1; i++) {
if(!less(a[i],a[i+1])){
return false;
}
}
return true;
}
}
选择排序
时间复杂度为
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度为
O
(
1
)
O(1)
O(1)(原地排序)
public class Slections {
public void SlectionSort(Comparable[] a){
int len = a.length;
for (int i = 0; i < len-1; i++) {
for (int j = i; j < len; j++) {
if(less(a[i],a[j])){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
public static boolean less(Comparable v, Comparable w){
//comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
return v.compareTo(w)<0;
}
public static void exch(Comparable[] a,int i ,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void show(Comparable[] a){
for (Comparable comparable : a) {
System.out.print(comparable + " ");
}
System.out.println();
}
public static boolean isSorted(Comparable[] a){
for (int i = 0; i < a.length-1; i++) {
if(!less(a[i],a[i+1])){
return false;
}
}
return true;
}
public static void main(String[] args) {
Slections slections = new Slections();
Comparable[] a = {"f","z","c","m","a"};
slections.SlectionSort(a);
slections.show(a);
}
}
output: z m f c a
插入排序
插入排序的时间复杂度是O(n^2)
空间复杂度是O(1)(原地排序)
public class Slections {
public void SlectionSort(Comparable[] a){
int len = a.length;
for (int i = 0; i < len-1; i++) {
for (int j = i; j < len; j++) {
if(less(a[i],a[j])){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
public static boolean less(Comparable v, Comparable w){
//comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
return v.compareTo(w)<0;
}
public static void exch(Comparable[] a,int i ,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void show(Comparable[] a){
for (Comparable comparable : a) {
System.out.print(comparable + " ");
}
System.out.println();
}
public static boolean isSorted(Comparable[] a){
for (int i = 0; i < a.length-1; i++) {
if(!less(a[i],a[i+1])){
return false;
}
}
return true;
}
public static void main(String[] args) {
Slections slections = new Slections();
Comparable[] a = {"f","z","c","m","a"};
slections.SlectionSort(a);
slections.show(a);
}
}
output: a c f m z
归并排序
这里的代码参考自算法第四版。
归并排序的时间复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
public class Merge {
private Merge() { }
//代码来自算法第四版,这里aux是辅助空间,这样递归时就无需开辟新的空间
private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
// precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
assert isSorted(a, lo, mid);
assert isSorted(a, mid+1, hi);
// copy to aux[]
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
}
// merge back to a[]
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if (i > mid) a[k] = aux[j++];
else if (j > hi) a[k] = aux[i++];
else if (less(aux[j], aux[i])) a[k] = aux[j++];
else a[k] = aux[i++];
}
// postcondition: a[lo .. hi] is sorted
assert isSorted(a, lo, hi);
}
// mergesort a[lo..hi] using auxiliary array aux[lo..hi]
private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid);
sort(a, aux, mid + 1, hi);
merge(a, aux, lo, mid, hi);
}
public static void sort(Comparable[] a) {
Comparable[] aux = new Comparable[a.length];
sort(a, aux, 0, a.length-1);
assert isSorted(a);
}
/***************************************************************************
*来自模板的粗著函数
***************************************************************************/
public static boolean less(Comparable v, Comparable w){
//comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
return v.compareTo(w)<0;
}
public static void exch(Comparable[] a,int i ,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void show(Comparable[] a){
for (Comparable comparable : a) {
System.out.print(comparable + " ");
}
System.out.println();
}
public static boolean isSorted(Comparable[] a){
for (int i = 0; i < a.length-1; i++) {
if(!less(a[i],a[i+1])){
return false;
}
}
return true;
}
}
快速排序
快速排序是每次排序选定一个值大的放其左边,小的放其右边的一种算法
快速排序的时间复杂度是
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn),空间复杂度是
O
(
1
)
O(1)
O(1).
public class Quick {
// This class should not be instantiated.
private Quick() { }
/**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
assert isSorted(a);
}
// quicksort the subarray from a[lo] to a[hi]
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int j = partition(a, lo, hi);
sort(a, lo, j-1);
sort(a, j+1, hi);
assert isSorted(a, lo, hi);
}
// partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
// and return the index j.
private static int partition(Comparable[] a, int lo, int hi) {
int i = lo;
int j = hi + 1;
Comparable v = a[lo];
while (true) {
// find item on lo to swap
while (less(a[++i], v)) {
if (i == hi) break;
}
// find item on hi to swap
while (less(v, a[--j])) {
if (j == lo) break; // redundant since a[lo] acts as sentinel
}
// check if pointers cross
if (i >= j) break;
exch(a, i, j);
}
// put partitioning item v at a[j]
exch(a, lo, j);
// now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
return j;
}
public static Comparable select(Comparable[] a, int k) {
if (k < 0 || k >= a.length) {
throw new IllegalArgumentException("index is not between 0 and " + a.length + ": " + k);
}
StdRandom.shuffle(a);
int lo = 0, hi = a.length - 1;
while (hi > lo) {
int i = partition(a, lo, hi);
if (i > k) hi = i - 1;
else if (i < k) lo = i + 1;
else return a[i];
}
return a[lo];
}
public static boolean less(Comparable v, Comparable w){
//comparable 比较类当v>w时返回1,v==w时返回0,v<w时返回-1;
return v.compareTo(w)<0;
}
public static void exch(Comparable[] a,int i ,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void show(Comparable[] a){
for (Comparable comparable : a) {
System.out.print(comparable + " ");
}
System.out.println();
}
public static boolean isSorted(Comparable[] a){
for (int i = 0; i < a.length-1; i++) {
if(!less(a[i],a[i+1])){
return false;
}
}
return true;
}
}
堆排序
堆排序有上浮和下沉两个操作,二叉堆是一个每个节点都大于他的子节点。
public class Heap {
public void HeapSort(Comparable[] a){
int N = a.length;
for (int i = N/2; i >=1; i--) {
sink(a,i);
}
}
//上浮操作
private void swim(Comparable[] a, int k){
while (k>1 && k/2<k){
Comparable temp;
temp = a[k];
a[k] = a[k/2];
a[k/2] = temp;
k= k/2;
}
}
//下沉操作
private void sink(Comparable[] a,int k){
while (2*k < a.length-1){
int j = 2*k;
if(j<a.length && a[j].compareTo(a[j+1])<0){
j++;
}
if(! (a[j].compareTo(a[j+1])<0)){
break;
}
Comparable temp = a[k];
a[k] = a[j];
a[j] = temp;
k = j;
}
}
public static void show(Comparable[] a){
for (Comparable comparable : a) {
System.out.print(comparable + " ");
}
System.out.println();
}
public static void main(String[] args) {
Heap heap = new Heap();
Comparable[] a = {"f","z","c","m","a"};
heap.HeapSort(a);
heap.show(a);
}
}
查找算法
二分查找
二分查找是对有序数组的一种查找方式,每次选取中间的元素与目标元素作比较,然后不断缩小范围的一种排序手段。
public class BinarySerch {
private boolean Serch(Comparable[] a, Comparable target,int lo,int hi){
if(a.length == 0 || lo>hi){
return false;
}
int mid = (lo+hi)/2;
if(a[mid] == target){
return true;
}else if(a[mid].compareTo(target) < 0){
return Serch(a,target,mid+1,hi);
}else {
return Serch(a,target,lo,mid-1);
}
}
public boolean Serch(Comparable[] a, Comparable target){
return Serch( a, target,0,a.length-1);
}
}
模糊二分查找
查找比目标值大的第一个元素,用到了二分查找查找到最小范围后的第一个数就是其目标值。
public class BinarySercheApplacation {
public Comparable SerchFirtBiggerNumber(Comparable[] a,Comparable target){
if(a.length == 0){
return null;
}
if(a[0].compareTo(target)<0){
return a[0];
}
if(a[a.length].compareTo(target)<0){
return null;
}
int n = a.length, left = 0, right = n;
while (left < right) {
int mid = left + (right - left) / 2;
if (a[mid].compareTo(target)<=0) left = mid + 1;
else right = mid;
}
return a[right];
}
}