1.二分查找
又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置
的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,
则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。直接上代码
// 二分查找
public static int biSearch(int[] array, int a) {
int lo = 0;
int hi = array.length - 1;
int mid;
while (lo <= hi) {
mid = (lo + hi) / 2;// 中间位置
if (array[mid] == a) {
return mid + 1;
} else if (array[mid] < a) { // 向右查找
lo = mid + 1;
} else { // 向左查找
hi = mid - 1;
}
}
return -1;
}
2.冒泡排序算法
(1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。
(2)这样对数组的第 0 个数据到 N-1 个数据进行一次遍历后,最大的一个数据就“沉”到数组第
N-1 个位置。
(3)N=N-1,如果 N 不为 0 就重复前面二步,否则排序完成。
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i -1; j++) {
if (array[j] > array[j + 1]) {
int temp;
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
3.插入排序算法
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
插入排序非常类似于整扑克牌。在开始摸牌时,左手是空的,牌面朝下放在桌上。接着,
一次从
桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。为了找到这张牌的正确位置,要将
它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。
如果输入数组已经是排好序的话,插入排序出现最佳情况,其运行时间是输入规模的一个线性函
数。如果输入数组是逆序排列的,将出现最坏情况。平均情况与最坏情况一样,其时间代价是(n2)。
public void sort(int arr[]) {
for (int i = 1; i < arr.length; i++) {
// 插入的数
int insertVal = arr[i];
// 被插入的位置(准备和前一个数比较)
int index = i - 1;
// 如果插入的数比被插入的数小
while (index >= 0 && insertVal < arr[index]) {
// 将把 arr[index] 向后移动
arr[index + 1] = arr[index];
// 让 index 向前移动
index--;
}
// 把插入的数放入合适位置
arr[index + 1] = insertVal;
}
}
4.快速排序算法
快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),
比基准值大的都在右边(一般是无序的)。一般选择序列的第一个元素。
一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有
继续比较下一个,直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比
较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的
值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值
来说,左右两边就是有序的了。
//快速排序
public void sort(int[] a, int low, int high) {
int start = low;
int end = high;
int key = a[low];
while (end > start) {
// 从后往前比较
while (end > start && a[end] >= key)
// 如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
end--;
if (a[end] <= key) {
int temp = a[end];
a[end] = a[start];
a[start] = temp;
}
// 从前往后比较
while (end > start && a[start] <= key)
// 如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
start++;
if (a[start] >= key) {
int temp = a[start];
a[start] = a[end];
a[end] = temp;
}
// 此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的
}
// 递归
if (start > low)
sort(a, low, start - 1);// 左边序列。第一个索引位置到关键值索引-1
if (end < high)
sort(a, end + 1, high);// 右边序列。从关键值索引+1 到最后一个
}
5.希尔排序算法
// 希尔排序
private void shellSort(int[] a) {
int dk = a.length / 2;
while (dk >= 1) {
ShellInsertSort(a, dk);
dk = dk / 2;
}
}
private void ShellInsertSort(int[] a, int dk) {
// 类似插入排序,只是插入排序增量是 1,这里增量是 dk,把 1 换成 dk 就可以了
for (int i = dk; i < a.length; i++) {
if (a[i] < a[i - dk]) {
int j;
int x = a[i];// x 为待插入元素
a[i] = a[i - dk];
for (j = i - dk; j >= 0 && x < a[j]; j = j - dk) {
// 通过循环,逐个后移一位找到要插入的位置。
a[j + dk] = a[j];
}
a[j + dk] = x;// 插入
}
}
}
6.桶排序算法
桶排序的基本思想是: 把数组 arr 划分为 n 个大小相同子区间(桶),每个子区间各自排序,最
后合并 。计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
1.找出待排序数组中的最大值 max、最小值 min
2.我们使用 动态数组 ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(max
min)/arr.length+1
3.遍历数组 arr,计算每个元素 arr[i] 放的桶
4.每个桶各自排序
public static void bucketSort(int[] arr) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
// 创建桶
int bucketNum = (max - min) / arr.length + 1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for (int i = 0; i < bucketNum; i++) {
bucketArr.add(new ArrayList<Integer>());
}
// 将每个元素放入桶
for (int i = 0; i < arr.length; i++) {
int num = (arr[i] - min) / (arr.length);
bucketArr.get(num).add(arr[i]);
}
// 对每个桶进行排序
for (int i = 0; i < bucketArr.size(); i++) {
Collections.sort(bucketArr.get(i));
}
}
7.基数排序算法
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位
开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序
列。
class radixSort {
int a[] = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 101, 56, 17, 18, 23, 34, 15,
35, 25, 53, 51 };
public radixSort() {
sort(a);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
public void sort(int[] array) {
// 首先确定排序的趟数;
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
int time = 0;
// 判断位数;
while (max > 0) {
max /= 10;
time++;
}
// 建立 10 个队列;
List<ArrayList> queue = new ArrayList<ArrayList>();
for (int i = 0; i < 10; i++) {
ArrayList<Integer> queue1 = new ArrayList<Integer>();
queue.add(queue1);
}
// 进行 time 次分配和收集;
for (int i = 0; i < time; i++) {
// 分配数组元素;
for (int j = 0; j < array.length; j++) {
// 得到数字的第 time+1 位数;
int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
ArrayList<Integer> queue2 = queue.get(x);
queue2.add(array[j]);
queue.set(x, queue2);
}
int count = 0;// 元素计数器;
// 收集队列元素;
for (int k = 0; k < 10; k++) {
while (queue.get(k).size() > 0) {
ArrayList<Integer> queue3 = queue.get(k);
array[count] = queue3.get(0);
queue3.remove(0);
count++;
}
}
}
}
}