公共代码
- 打印数组
// 打印数组公用函数
public void printArr(int[] arr) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
if (i != (arr.length - 1)) {
System.out.print(arr[i] + ",");
} else {
System.out.print(arr[i] + "]");
System.out.println();
}
}
}
- 不用中间变量实现两个变量的交换
用异或的方式:
public static void main(String[] args) {
int x = 8;
int y = 9;
//交换两个变量
x = x ^ y;
y = x ^ y;
x = x ^ y;
System.out.println("x=" + x + ";" + "y=" + y);
}
打印输出:x=9;y=8
冒泡排序
原理
冒泡排序也是最简单的排序方式,其原理就是比较两个相邻的元素,将值大的元素交换到右边。
代码
// 冒泡排序
public void bubbleSort() {
int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5,};
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] > array[j]) {
//使用异或来交换,不用中间变量
//^是针对二进制的二目运算符。运算规则:两个二进制数值如果在同一位上相同,则结果中该位为0,否则为1
array[i] = array[i] ^ array[j];
array[j] = array[i] ^ array[j];
array[i] = array[i] ^ array[j];
}
}
}
printArr(array);
}
快速排序
原理
- 先从数列中取出一个数作为基准数。
- 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 再对左右区间重复第二步,直到各区间只有一个数。
代码
//快速排序
public void quickSort() {
int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5,14};
sort(array, 0, array.length - 1);
}
public void sort(int arr[], int low, int high) {
int key = arr[low];
int start = low;
int end = high;
while (start < end) {
// 如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
while (start < end && arr[end] >= key) {
end--;
}
if (start < end && arr[end] < key) {
arr[start] = arr[start] ^ arr[end];
arr[end] = arr[start] ^ arr[end];
arr[start] = arr[start] ^ arr[end];
}
// 如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
while (start < end && arr[start] <= key) {
start++;
}
if (start < end && arr[start] > key) {
arr[start] = arr[start] ^ arr[end];
arr[end] = arr[start] ^ arr[end];
arr[start] = arr[start] ^ arr[end];
}
}
// 此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
printArr(arr);
//此时 start == end 都为关键值的索引位置
//先判断start>low再次经行左边排序
//左边序列。第一个索引位置到关键值索引-1
if (start > low) {
sort(arr, low, start - 1);
}
//左边依次排序执行完递归后,弹栈进行右边排序
// 右边序列。从关键值索引+1到最后一个
if (end < high) {
sort(arr, start + 1, high);
}
}
选择排序
原理
选择排序,从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列。
代码
//选择排序
public void chooseSort() {
int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5};
int minIndex = 0;
for (int i = 0; i < array.length; i++) {
//问题的关键就是要找到后面最小的那个值 然后交换位置
minIndex = i;
for (int j = i; j < array.length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
//两个值相等时不做交换
if (i == minIndex) {
continue;
}
//交换位置
array[i] = array[i] ^ array[minIndex];
array[minIndex] = array[i] ^ array[minIndex];
array[i] = array[i] ^ array[minIndex];
printArr(array);
}
printArr(array);
}
插入排序
原理
直接插入的算法基本思想是:仅有一个元素的序列总是有序的,因此,对n个记录的序列,可从第二个元素开始直接到第n个元素,逐个向有序序列中执行插入操作,从而得到n个元素按关键字有序的序列
代码
//插入排序
public void insertSort() {
int[] array = {51, 12, 53, 1, 5, 64, 77, 89, 14, 124, 54, 3, 5};
for (int i = 1; i < array.length; i++) {
int key = array[i];
int j = i - 1;
//当后面的元素值大于前面的元素值时执行插入
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
printArr(array);
}
二分法查找
实现查找指定数值在元素有序的数组中存储的位置(索引),返回该位置(索引)
原理
- 首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
- 如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。
- 如果某一步数组为空,则表示找不到目标元素。
代码
//二分法查找
public void binarySearch() {
int array[] = {1, 3, 5, 5, 12, 14, 51, 53, 54, 64, 77, 89, 124, 135};
int searchKey = 77;
int index = search(array, searchKey);
System.out.println("index = "+ index);
}
//二分查找法(折半查找法)
public static int search(int[] arr, int number) {
int min = 0; //最小下标
int max = arr.length - 1; //最大下标
int mid = 0; //中间下标
while (min <= max) {
//没找到,更新范围继续找
mid = (min + max) / 2;
if (arr[mid] > number) { //number在mid的左边
max = mid - 1; //改变最大下标
} else if (arr[mid] < number) { //number在mid的右边
min = mid + 1; //改变最小下标
} else {
return mid;
}
}
return -1;
}