1. 常见的数据结构
- List 列表:有序,包含多种类型的对象
- Arrays 数组:有序,在创建时确定大小,具有索引,插入/删除效率低
- Linked List 链表:没有索引,每个节点指向下一个节点,插入/删除简单
- Stack 堆栈:后进先出,Push进栈,Pop出栈
- Queue 队列:先进先出,Enqueue入队,Dequeue出队
2. 冒泡排序
每一轮比较相邻两数,若左边的数较大,交换
public static void bubbleSort(int[] a) {
int temp = 0;
int len = a.length;
for (int i = 0; i < len; i++) {
for (int j = 1; j < len - i; j++) {
if (a[j-1] > a[j]) {
temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
}
}
}
}
时间复杂度 O(n2),空间复杂度 O(1)
3. 选择排序
每轮从n+1至末尾的数列中选择最小的数放到第n个位置上
public static void selectSort(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < a.length; j++) {
if (a[j] < a[minIndex]) minIndex = j;
}
if (minIndex != i) {
int temp = a[i];
a[i] = a[minIndex];
a[minInex] = temp;
}
}
}
时间复杂度 O(n2),空间复杂度 O(1)
3. 插入排序
假定前n个数有序,每轮将第n+1个数插入到前面的序列中
public static void insertSort(int[] a) {
int temp = 0;
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j > 0; j--) {
if (a[j] < a[j-1]) {
temp = a[j];
a[j] = a[j-1];
a[j-1] = a[j];
} else {
break;
}
}
}
}
时间复杂度 O(n2),空间复杂度O(1)
4. 快速排序
选定一个基准,对数列进行排列,保证比基准小的数都在其左侧,大的数都在其右侧,再对两边的子序列进行同样操作
public static void quickSort(int[] a, int l; int r) {
if (l >= r) return;
int pivot = a[l]; int i = l; int j = r;
while (i < j) {
while (i < j && a[j] >= pivot) {
j--;
}
if (i < j) a[i] = a[j];
while (i < j && a[i] <= pivot) {
i++;
}
if (i < j) a[j] = a[i];
}
a[i] = pivot;
quickSort(a, l, i-1);
quickSort(a, i+1, r);
}
时间复杂度 O(nlogn),空间复杂度 O(logn)
5. 归并排序
递归的分解数列至每个子数列只有一个数(即子数列为有序的),再合并所有数列
public static void mergeSort(int[] a, int low, int high) {
if (low >= high) return;
int mid = (low + high) / 2;
mergeSort(a, low, mid);
mergeSort(a, mid + 1, high);
merge(a, low, mid, high);
}
public static void merge(int[] a, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= high) {
if (a[i] < a[j]) {
temp[k++] = a[i++];
} else {
temp[k++] = a[j++];
}
}
while (i <= mid) temp[k++] = a[i++];
while (j <= high) temp[k++] = a[j++];
for (int n = 0; n < temp.length; n++) {
a[low + n] = temp[n];
}
}
时间复杂度O(nlogn),空间复杂度O(n)
6. 二分查找
要求是一个有序序列,每次以序列中间位置与要查找的数比较,缩小一半范围,直至匹配成功
递归方法
public static int binarySearch(int[] a, int key, int low, int high) {
if (low > high || a[low] > key || a[high] < key) return -1;
int middle = (low + high) / 2;
if (a[middle] > key) {
binarySearch(a, key, low, middle - 1);
} else if (a[middle] < key) {
binarySearch(a, key, midddle + 1, high);
} else {
return middle;
}
}
时间复杂度 O(logn),空间复杂度 O(logn)
非递归方法
public static int binarySearch(int[] a, int key) {
int low = 0;
int high = a.length - 1;
int middle = 0;
if (a[low] > key || a[high] < key || low > high) return -1;
while (low <= high) {
middle = (low + high) / 2;
if (a[middle] < key) {
low = middle + 1;
} else if (a[middle] > key) {
high = middle - 1;
} else {
return middle;
}
}
return -1;
}
时间复杂度 O(logn),空间复杂度 O(1)