虽然很经典,虽然也很久了,但是我还是想发个博客啊哈哈哈,不好意思打扰了
二分查找(这个送的哈)
public static boolean binarySearch(final List<Integer> numbers, final Integer value) {
if (numbers == null || numbers.isEmpty()) {
return false;
}
final Integer comparison = numbers.get(numbers.size() / 2);
if (value.equals(comparison)) {
return true;
}
if (value < comparison) {
return binarySearch(numbers.subList(0, numbers.size() / 2), value);
} else {
return binarySearch(numbers.subList(numbers.size() / 2, numbers.size()), value);
}
}
冒泡排序:
冒泡排序虽然很经典但是还是有可以优化的地方,如下,有优化的地方吗? 还是有的,比如[8,1,2,3,4,5,6,7], 只需一次就好了,那接下来的循环不就浪费了?可以设置一个标志位
private void bubbleSort(int[] a) {
boolean isSort;
for (int i = 0; i < a.length; i++) {
isSort = false;
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j + 1] < a[j]) {
int temp;
temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
isSort = true;
}
}
if (!isSort) {
return; //到此就结束了。
}
}
System.out.println(Arrays.toString(a));
}
堆排序:
public class HeapSort {
private static int[] data = {3, 6, 23, 4, 3, 2, 9, 10, 18, 11};
//建立大根堆
public void buildMaxHeap(int[] data, int lastIndex) {
//根据当前的lastIndex,计算对应的第一个父节点
for (int i = lastIndex / 2; i >= 0; i--) {
int k = i;
while (2 * k + 1 <= lastIndex) {
int biggerIndex = 2 * k + 1; //存放左右节点中最大的索引
if (biggerIndex < lastIndex) { //说明有右节点
if (data[biggerIndex] < data[biggerIndex + 1]) {
biggerIndex++; //存放左右节点中较大的
}
}
//如果当前的父节点小于左右子节点 中最大的,则进行交换
if (data[k] < data[biggerIndex]) {
swap(data, k, biggerIndex);
k = biggerIndex; //交换了之后上边满足了,可能下边又不满足了
} else { //如果是满足的那么停止掉while 循环
break;
}
}
}
}
//交换两个节点的值
public void swap(int[] data, int i, int j) {
int tmp;
tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}
//排序主方法
public void heapSort(int[] data) {
for (int i = 0; i < data.length - 1; i++) {
buildMaxHeap(data, data.length - 1 - i);
//建立好一次大顶堆之后,交换第一个和最后一个,然后再进行剩余的建堆
swap(data, 0, data.length - 1 - i);
System.out.print("第" + i + "趟排序 ");
System.out.println(Arrays.toString(data));
}
}
@Test
public void testHeapSort() {
heapSort(data);
}
插入排序:
//在原有的空间上进行插入排序
private void insertSort(int[] a) {
int insertNum; //存放要插入的数
int arrayLength = a.length;
for (int i = 1; i < arrayLength; i++) {
insertNum = a[i];
int j = i - 1; //存放要比较的索引(当前已经排好序的部分)
while (j >= 0 && a[j] > insertNum) { //循环将排好序的数都往后移动
a[j + 1] = a[j];
j--;
}
a[j + 1] = insertNum;
}
}
//思路2 在新的集合中插入元素,比较简单,不再写
归并排序:
public List<Integer> mergetSort(final List<Integer> values) {
if (values.size() < 2) {
return values;
}
final List<Integer> leftHalf = values.subList(0, values.size() / 2); //from 包含,to 不包含
final List<Integer> rightHalf = values.subList(values.size() / 2, values.size()); //from 包含,to 不包含
return merge(mergetSort(leftHalf), mergetSort(rightHalf));
}
private List<Integer> merge(List<Integer> left, List<Integer> right) {
final List<Integer> returnTo = new ArrayList<>(); //from 包含,to 不包含
//记录左侧和右侧合并的位置
int leftAttr = 0;
int rightAttr = 0;
while (leftAttr < left.size() && rightAttr < right.size()) {
//执行合并
if (left.get(leftAttr) < right.get(rightAttr)) {
returnTo.add(left.get(leftAttr));
leftAttr++;
} else {
returnTo.add(right.get(rightAttr));
rightAttr++;
}
//将左侧剩余的或者右侧剩余的直接添加到集合之中
while (leftAttr < left.size()) {
returnTo.add(left.get(leftAttr));
leftAttr++;
}
while (rightAttr < right.size()) {
returnTo.add(right.get(rightAttr));
rightAttr++;
}
}
return returnTo;
}
快速排序:
public static void main(String[] args) {
List<Integer> list = quickSort(numbers);
for (Integer integer : list) {
System.out.print(integer + " ");
}
}
public static List<Integer> quickSort(List<Integer> numbers) {
if (numbers.size() < 2) {
return numbers;
}
//基准
final Integer pivot = numbers.get(0);
final List<Integer> lower = new ArrayList<>();
final List<Integer> higher = new ArrayList<>();
for (int i = 1; i < numbers.size(); i++) {
if (numbers.get(i) < pivot) {
lower.add(numbers.get(i));
} else {
higher.add(numbers.get(i));
}
}
final List<Integer> sorted = quickSort(lower);
sorted.add(pivot);
sorted.addAll(quickSort(higher));
return sorted;
}
简单选择排序:
/**
* @author **
* <p>
* 常用于取序列中最大最小的几个数时。
* (如果每次比较都交换,那么就是交换排序;如果每次比较完一个循环再交换,就是简单选择排序。)
* 遍历整个序列,将最小的数放在最前面。
* 遍历剩下的序列,将最小的数放在最前面。
* 重复第二步,直到只剩下一个数。
* <p>
* 如何写成代码:
* 首先确定循环次数,并且记住当前数字和当前位置。
* 将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。
* 比对完成后,将最小的值与第一个数的值交换。
* 重复2、3步。
*/
public class SimpleSelectionSort {
private static int a[] = {2, 1, 5, 8, 7, 6};
public static void main(String[] args) {
simpleSelectionSort(a);
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
}
//执行排序的方法
public static void simpleSelectionSort(int a[]) {
int length = a.length;
for (int i = 0; i < length; i++) { //循环次数
int key = a[i]; //刚开始先假设剩下没有排序的第一个为最小值,以后不断更新这两个值
int position = i;
for (int j = i + 1; j < length; j++) { //从剩下的序列中找出最小的值,和其位置
if (a[j] < key) { //如果查找到值小于当前找到的最小值,则更新最小值和最小值所在的位置
position = j;
key = a[j];
}
}
a[position] = a[i];
a[i] = key; //最小值赋值给需要排的当前位
}
}
}