排序
冒泡排序(Bubble Sort)
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较.
例如:
下面是冒泡排序代码 。
public class _03_ArrayBubbleSort {
public static void main(String[] args) {
int[] arr = { 3, 2, 4, 5, 1 };
bubbleSort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public static void bubbleSort(int[] arr) {
// 1 比较相邻的两个元素,如果第一个比第二大,就交换位置
// for (int j = 0; j < arr.length; j++) {
// for (int i = 0; i < arr.length-1; i++) {
// if (arr[i] > arr[i+1]) {
// int temp = arr[i];
// arr[i] = arr[i+1];
// arr[i+1] = temp;
// }
// }
// }
int count = 0;
// 决定循环次数(每一轮比较 作为一次循环)
for (int i = 0; i < arr.length-1; i++) {
// 决定每次循环的次数
// 因为每循环一次,都会把最大的放后面,所以 最后的元素不需要比较
// 因此 每次循环比较的次数,递减
for (int j = 0; j < arr.length-1-i; j++) {
count++;
// 比较相邻元素
if (arr[j] > arr[j+1]) {
// 交换位置
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
// 3, 2, 4, 5, 1 0
// 2, 3, 4, 1, 5 1 i=0
// 2, 3, 1, 4, 5 2 i=1
// 2, 1, 3, 4, 5 3 i=2
// 1, 2, 3, 4, 5 4 i=3
}
System.out.println("循环执行了 : "+count);
}
}
选择排序
1.每次从待排序的数据元素中选出最小(或最大)的一个元素,先拿出第一个,假设是最小的,然后挨个和后面的比较,全部比较完之后,如果有比这个元素小的,就换位
2 嵌套循环比较
举例:
2、算法过程
- 举个栗子(第一趟的排序过程)
原始序列:49、38、65、97、76、13、27、49
1)在进行选择排序过程中分成有序和无序两个部分,开始都是无序序列
结果:49、38、65、97、76、13、27、49
2)从无序序列中取出最小的元素13,将13同无序序列第一个元素交换,此时产生仅含一个元素的有序序列,无序序列减一
结果:{13、} {38、65、97、76、49、27、49}
3)从无序序列中取出最小的元素27,将27同无序序列第一个元素交换,此时产生仅两个元素的有序序列,无序序列减一
结果:{13、27、} {65、97、76、49、38、49}
4)从无序序列中取出最小的元素38,将38同无序序列第一个元素交换,此时产生含三个元素的有序序列,无序序列减一
结果:{13、27、38、} {97、76、49、65、49}
5)从无序序列中取出最小的元素49,将49同无序序列第一个元素交换,此时产生含四个个元素的有序序列,无序序列减一
结果:{13、27、38、49、} {76、97、65、49}
6)从无序序列中取出最小的元素49,将49同无序序列第一个元素交换,此时产生含五个元素的有序序列,无序序列减一
结果:{13、27、38、49、49、} {97、65、76}
7)从无序序列中取出最小的元素65,将65同无序序列第一个元素交换,此时产生含六个元素的有序序列,无序序列减一
结果:{13、27、38、49、49、65} {97、76}
8)从无序序列中取出最小的元素76,将76同无序序列第一个元素交换,此时产生含七个元素的有序序列,无序序列减一
结果:{13、27、38、49、49、65、76、} {97}
9)最后一个元素肯定是最大元素,无序排序直接生产一个有序的序列
实现代码::
public class _04_ArraySelectSort {
public static void main(String[] args) {
int[] arr = { 3, 2, 4, 5, 1 };
selectSort(arr);
for (int i : arr) {
System.out.println(i);
}
}
public static void selectSort(int[] arr){
for (int i = 0; i < arr.length; i++) {
// 假设 第一个是最小的
int min = i;
// 因为i是当前元素,要和后面的比较,就要从 i+1开始比较
// 这里一定不能写0,否则结果就不对了
for (int j = i+1; j < arr.length; j++) {
// 判断 min 是否是最小值
if (arr[min] > arr[j]) {
// 如果j位的值 比 min 小,就把这个小的下标赋值给 min
min = j;
}
}
// 如果 min 不等于i 说明 有比i 还小的值,就交换位置
if (min != i) {
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
// 3, 2, 4, 5, 1 i=0 , min=1
}
}
}
API排序
导入import java.util.Arrays;包
public class _05_ArrayAPI {
public static void main(String[] args) {
int[] arr = { 3, 2, 4, 5, 1 };
// 报错,找不到这个类,只写类名,默认来当前包内找该类
// _10_Array.m1(2);
_01_Basic._10_Array.m1(2);
// 默认从小到大
// 要写类全名(包名.类名)
java.util.Arrays.sort(arr);
// 注意导包 : import java.util.Arrays;
// 如果导包了,可以直接写该类类名
Arrays.sort(arr);
for (int i : arr) {
System.out.println(i);
}
}
}
查找
顺序查找
1 遍历数组,挨个比较
2 如果有和目标元素相等的,就返回该下标
3 如果循环完,都没有发现相等的,就返回-1
代码:::
public class _06_ArrayBinarySearch {
public static void main(String[] args) {
int[] arr = {1,4,6,7,2,11,55,7};
int index = m1(arr, 7);
System.out.println(index);
}
public static int m1(int[] arr, int include) {
// 顺序查找
for (int i = 0; i < arr.length; i++) {
if (arr[i] == include) {
return i;
}
}
return -1;
}
}
优点:简单
缺点:查询效率低下
二分法查找
1.二分法查找的前提是数组为有序
2.数据若有重复元素,先找到哪个算哪个
3.二分法查找用于查找固定有序的的数据
算法实现;
1.确定起始位置
2.确定中间数据,是否为要查找的数据,如果是则查找成功直接返回
3.若目标数据小于中间数值,则起始位置不变,终止位置为中间值-1
4.如果目标数据大于中间数据,则 结束值不变,起始值 为 中间值 +1
5 如果 起始值 大于 结束值 终止比较,说明不存在.
6 重复执行以上操作即可
例如
假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2.
1.开始令front=0(指向3),end=7(指向88),则mid=3(指向36)。因为a[mid]>x,故应在前半段中查找。
2.令新的end=mid-1=2,而front=0不变,则新的mid=1。此时x>a[mid],故确定应在后半段中查找。
3.令新的front=mid+1=2,而end=2不变,则新的mid=2,此时a[mid]=x,查找成功。
如果要查找的数不是数列中的数,例如x=25,当第三次判断时,x>a[mid],按以上规律,令front=mid+1,即front=3,出现front>end的情况,表示查找不成功。
Java代码实现:
public class _07_BinarySearch {
public static void main(String[] args) {
int[] arr = new int[99999999];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
int index = search(arr, 9999999);
System.out.println(index);
}
public static int search(int[] arr, int num) {
int count = 0;
// 起始位置
int startPos = 0;
// 结束位置
int endPos = arr.length-1;
// 中间下标
int m = (startPos+endPos) / 2;
// 当起始下标 大于 结束下标时 终止
while( startPos <= endPos){
count++;
// 判断中间值 是否为 目标数据
if (arr[m] == num) {
System.out.println("count : "+count);
return m;
}
// 判断目标数据 是否大于中间值
if (num > arr[m]) {
startPos = m+1;
}
// 判断目标数据 是否小于中间值
if (num < arr[m]) {
endPos = m-1;
}
// 重新计算中间值
m = (startPos + endPos) /2;
}
System.out.println("count : "+count);
return -1;
}
}