1、冒泡排序
时间复杂度:O(n2)
public class bubble {
public static void main(String[] args) {
int[] arr = {3, 4, 10, 5, 2};
bubbleSort(arr);
}
public static void bubbleSort(int[] arr) {
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid");
return;
}
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
2、选择排序
时间复杂度:O(n2)
public class select {
public static void main(String[] args) {
int[] arr = {2, 1, 8, 6, 7, 10};
selectSort(arr);
}
public static void selectSort(int[] arr) {
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid");
return;
}
for (int i = 0; i < arr.length - 1; i++) {
int index = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[index]) {
index = j;
}
}
if (index != i) {
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
}
System.out.println(Arrays.toString(arr));
}
}
3、插入排序
时间复杂度:O(n2)
public class InsertSort {
public static void main(String[] args) {
int[] arr = {20, 10, 8, 11, 15, 4};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
public static boolean insertSort(int[] arr) {
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid!!!");
return false;
}
for (int i = 1; i < arr.length; i++) {
int index = i;
int current = arr[i];
for (int j = i - 1; j >= 0; j--) {
if (arr[j] < current) {
arr[j + 1] = arr[j];
index--;
} else {
break;
}
}
if (index != i) {
arr[index] = current;
}
}
return true;
}
}
4、快速排序
时间复杂度:O(n * log n)
public class QuicklySort {
/**
*快速排序算法代码实现
*@param arr int类型数组
*@param left int类型,排序起始位置
*@param right int类型,排序结束位置
*/
public static void quicklySort(int[] arr, int left, int right) {
//参数合法化判断
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid");
return;
}
//递归基线判断标准
if (left > right) {
return;
}
//定义变量,左索引位置,右索引位置,基础元素base和交换值
int l, r, base, temp;
l = left;
r = right;
base = arr[left];
//降序:从右边开始查找,找到比base大的数,跳出循环;从左边开始查找,找到比base小的数,跳出循环;
//交换两数值
while (l != r) {
while (arr[r] <= base && l < r) {
r--;
}
while (arr[l] >= base && l < r) {
l++;
}
//交换
if (l < r) {
temp = arr[r];
arr[r] = arr[l];
arr[l] = temp;
}
}
//base值回归中间
arr[left] = arr[l];
arr[l] = base;
//递归
quicklySort(arr, left, r - 1);
quicklySort(arr, l + 1, right);
}
public static void main(String[] args) {
int[] arr = {20, 10, 9, 5, 100, 44};
System.out.println("排序前" + Arrays.toString(arr));
quicklySort(arr, 0, arr.length - 1);
System.out.println("排序后" + Arrays.toString(arr));
}
}
5、二分查找
时间复杂度:O(log n)
class HalfSearch {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 9, 11, 13, 16, 20, 21, 100};
int find = 21;
int index = 0;
index = findIndexOf(arr, find);
if (-1 == index) {
System.out.println("未找到!!!");
} else {
System.out.println("Find at " + index);
}
}
/**
*二分法查找已经排序(从小到大)的数组元素
*@param arr int类型的目标数组
*@param find int类型要查找的目标元素
*@return int类型 返回所查找的元素所在的角标位置
返回-1表示没有找到或者函数运行失败
失败原因:1. 传入的arr数组为null; 2. arr数组长度为0
*/
public static int findIndexOf(int[] arr, int find) {
//参数合法化判断
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid!!!");
return -1;
}
/*
1.控制角标,定义max,min
2.定义index = -1 ,用于传回find所在的角标
3.与要查找的find进行循环比较:
3.1 mid = (max + min) / 2 在循环中反复重新定义
3.2 使用while循环判断,当min>max的时候终止循环
3.3 mid < find, min = mid + 1, 重新定义mid然后继续比较
3.4 mid > find, max = mid - 1, 重新定义mid然后继续比较
3.5 mid == find, 则index为对应的find的角标; break; 并返回index
*/
int max = arr.length - 1;
int min = 0;
int index = -1;
while (min <= max) {
int mid = (max + min) / 2;
if (arr[mid] < find) {
min = mid + 1;
} else if (arr[mid] > find) {
max = mid - 1;
} else {
index = mid;
break;
}
}
return index;
}
}
6、将某一个元素添加到某一个数组,不影响排序
基本思路就是:1.找到位置 2.插入,后面元素整体后移 3.这里将末尾位置用0(无效)元素替代
class Add {
public static void main(String[] args) {
int[] arr = {1, 2, 6, 10, 20, 56, 98, 0};
addNumberInArray(arr, 100);
printAddArray(arr);
}
/**
*将某一个元素数据插入到已排序的数组中,不影响原有数组顺序
*@param arr int类型的已经排序好的数组(从小到大),0为无效元素
*@param add int类型的需要插入的元素数据
*@return boolean 返回true表示函数运行成功,返回false表示运行失败
失败原因:1.传入的arr数组为null 2.arr数组长度为0
*/
public static boolean addNumberInArray(int[] arr, int add) {
/*
1.参数合法化判断
2.定义一个 int index = -1; 用来记录所插入位置的角标
3.找到要插入的位置,循环遍历数组,当 arr[i] > add 的时候,index记录位置
break;这样可以提升效率,避免不必要的循环
4.将add插入到数组中,从数组最大角标元素开始,即无效元素0开始,依次向后"替换":
4.1 这里需要判定,如果输入的数字大于任何一个数字,直接插入到数组最后
4.2 从 j = arr.length - 1 开始, j--, a[j] = a[j-1]; 一条语句即可替换
4.3 会空出 arr[index], 将add赋值即可
6.返回true
*/
//参数合法化判断
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid!!!");
return false;
}
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] > add) {
index = i;
break;
}
}
if (-1 != index) {
for (int j = arr.length - 1; j > index; j--) {
arr [j] = arr[j - 1];
}
arr[index] = add;
} else {
arr[arr.length - 1] = add;
}
return true;
}
/**
*遍历打印元素
*@param arr int类型的数组
*@return boolean 返回true表示函数运行成功,返回false表示运行失败
失败原因:1.传入的arr数组为null 2.arr数组长度为0
*/
public static boolean printAddArray(int[] arr) {
//参数合法化判断
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid!!!");
return false;
}
for (int i = 0; i < arr.length; i++) {
System.out.println("arr[" + i + "] = " + arr[i]);
}
return true;
}
}
7、删除数组中某一个元素,不影响排序
这里注意排重,将多个要删除的元素都删除,同样先找到元素,然后统计重复个数,然后删除,后面元素前移,末尾补0(无效元素)。
class Deletes {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 13, 13, 13, 15, 17, 19};
deleteNumberInArray(arr, 13);
printDeleteArray(arr);
}
/**
*删除已排好序的数组arr中的所有delete元素,有可能无法删除
*@param arr int类型已经排序好的数组,升序
*@param delete int类型要进行删除的元素数据
*@return boolean 返回true表示运行成功,返回false表示运行失败
失败原因:1.传入的arr数组为null; 2.arr数组长度为0
*/
public static boolean deleteNumberInArray(int[] arr, int delete) {
//参数合法性判断
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid!!!");
return false;
}
/*
函数功能实现过程:
1.找到要删除元素数据的角标 : 找到该元素; 找不到该元素
1.1 定义一个index = -1, 用于记录角标,默认是没有即-1; 定义一个count = 0, 用于记录要删除元素个数
1.2 循环遍历查找,如果找到,则index的值替换为对应元素的角标,并count++,然后进行结束循环判定:
1.2.1 因为是排序好的,所以要删除的元素的重复会集中在一起,因此要对下一个元素是否也为要删除元素
进行判定:如果是,继续循环;如果不是,结束循环
2.删除操作
2.1 判断index是否为-1,当为-1的时候,说明没找到,如果不是-1,则可以进行删除操作
2.2 删除步骤:
2.2.1 确定第一个delete元素的角标,为index + 1 - count = i
2.2.2 第i个元素会被第(i + count)个元素替换, i的最大值小于(arr.length - count),整体前移
3.最后的数据整体换为0,表示无效数据,返回true
*/
int index = -1;
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == delete) {
index = i;
count++;
//这里还要保证 i + 1 不能越界
if (i + 1 != arr.length && arr[i+1] == delete) {
continue;
} else {
break;
}
}
}
if (-1 != index) {
for (int i = index + 1 - count; i < arr.length - count; i++) {
arr[i] = arr[i + count];
}
for (int j = arr.length - 1; j >= arr.length - count; j--) {
arr[j] = 0;
}
} else {
System.out.println("查无此数据,无法删除!!!");
}
return true;
}
/**
*遍历打印删除操作后的数组
*@param arr int类型数组,从小到大排列,并进行了删除操作,末位0表示无效元素
*@return boolean 返回false表示运行失败,返回true表示运行成功
运行失败原因:1.传入的arr数组为null; 2.传入的arr数组长度为0
*/
public static boolean printDeleteArray(int[] arr) {
//参数合法性判断
if (null == arr || 0 == arr.length) {
System.out.println("Input param is invalid!!!");
return false;
}
for (int i = 0; i < arr.length; i++) {
System.out.println("arr[" + i + "] = " + arr[i]);
}
return true;
}
}