一。冒泡排序
简介(从小到大排序)
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个,即需要进行length-1次。
第一次是对n个数进行n-1次比较,进行到最后第n个的一个是最大的;
第二次是对n-1个数进行n-2次比较,进行到最后第n-1个的一个是最大的;
…
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码展示
package com.paixu;
import java.util.Arrays;
import java.util.Scanner;
public class maopao {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您想要排列数组的元素个数:");
int temp=sc.nextInt();
System.out.println("请输入"+temp+"数:");
int[] array=new int[temp];
for (int i=0;i< array.length;i++){
array[i]=sc.nextInt();
}
effervescence(array);
System.out.println("排序后的数组为:");
System.out.println(Arrays.toString(array));
}
public static void effervescence(int[] arr){
for (int i=0;i<arr.length;i++){
for (int j=0;j<arr.length-1;j++){
if (arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
}
代码运行结果:
时间复杂度为:
O(n^2)
空间复杂度:
只用到一个临时变量,空间复杂度O(n) = O(1)
二。选择排序
选择排序是一种简单直观的排序算法,其基本原理是每一次从待排序的数组里找到最小值(最大值)的下标,然后将最小值(最大值)跟待排序数组的第一个进行交换,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。反复的进行这样的过程直到待排序的数组全部有序。
操作步骤:
1>首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
2>再从剩余未排序元素中继续寻找最小(大)元素,然后放到未排序序列的起始位置。
3>重复第二步,直到所有元素均排序完毕。
代码展示
package com.paixu;
import java.util.Arrays;
import java.util.Scanner;
public class xuanze {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您想要排列数组的元素个数:");
int temp=sc.nextInt();
System.out.println("请输入"+temp+"数:");
int[] array=new int[temp];
for (int i=0;i< array.length;i++){
array[i]=sc.nextInt();
}
choice(array);
System.out.println("排序后的数组为:");
System.out.println(Arrays.toString(array));
}
public static void choice(int[] arr){
for (int i=0;i<arr.length;i++){
int min = i ;
for (int j=i+1;j<arr.length;j++ ){
if (arr[min]>arr[j]){
int temp=arr[j];
arr[j]=arr[min];
arr[min]=temp;
}
}
}
}
}
运行结果:
时间复杂度为O(n2)
空间复杂度为O(1)
三.快速排序
速排序是一种基于分而治之的排序算法,其中:
1、通过从数组中选择一个中心元素将数组划分成两个子数组,在划分数组时,将比中心元素小的元素放在左子数组,将比中心元素大的元素放在右子数组。
2、左子数组和右子数组也使用相同的方法进行划分,这个过程一直持续到每个子数组都包含一个元素为止。
3、最后,将元素组合在一起以形成排序的数组。
下图只是展示第一趟的过程,往后还会进行操作直到从小到大输出为止
代码展示:
主要方法:
package com.paixu;
import java.util.Scanner;
public class kuaisu {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入四个数");
int arr[]=new int[4];
for (int i=0;i<arr.length;i++){
arr[i]=sc.nextInt();
}
sort(arr,0,3);
System.out.println("排序后为:");
for (int i:arr){
System.out.print(i+"\t");
}
}
public static void sort(int[] arr,int left,int right){
if (left>right){
return;
}
int base=arr[left];
int i=left;
int j=right;
while (i!=j){
while (arr[j]>=base&&i<j ){
j--;
}
while (arr[i]<=base&&i<j){
i++;
}
int temp= arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
arr[left]=arr[i];
arr[i]=base;
sort(arr,left,i-1);
sort(arr,i+1,right);
}
}
运行测试:
算法分析
时间复杂度
最差:O(N^2),退化为冒泡排序
最优:O(NlogN)
平均:O(NlogN)
空间复杂度
递归调用消耗栈空间,因此为O(logN)
四.插入排序
每次选择无序区间的第一个元素,在有序区间内选择合适的位置插入
成, 然后再插入这个元素. 其中第一部分的排序也是通过再次拆分为两部分来进行的.
①. 从第一个元素开始,该元素已经默认被排序了;
②. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
③. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
④. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
⑤. 将新元素插入到该位置后;
⑥. 重复步骤②~⑤。
动图链接
代码如下:
package com.paixu;
import java.util.Arrays;
public class charu {
public static void insertSort(int[] array){
for (int i = 0; i <array.length ; i++) {
int tmp = array[i];
int j = i-1;
for ( ;j >=0; j--) {
if (array[j]>tmp){
array[j+1]=array[j];
}else
{
// array[j+1]=tmp;
break;
}
}
array[j+1]=tmp;
}
}
public static void main(String[] args) {
int[] array={10,6,9,3,5};
insertSort(array);
System.out.println(Arrays.toString(array));
}
}
运行结果如下:
时间复杂度:
最好情况时间复杂度为O(n)。
最坏情况时间复杂度为O(n^2)。
平均情况下时间复杂度为O(n^2)。
空间复杂度:O(1)。
五.二分查找
代码展示:
package com.paixu;
import java.util.Scanner;
public class erfen {
public static void main(String[] args) {
int[] arr={19,28,37,46,50};
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字:");
int num = sc.nextInt();
int temp=Find(arr,num);
if (temp==-1){
System.out.println("没有您要找的数,请重新输入");
}else {
System.out.println("查找的位置是:" + temp);
}
}
public static int Find(int[] arr,int num){
// 1.定义一个变量,记录左边元素的索引,初始值为0
int left = 0;
// 2.定义一个变量,记录右边元素的索引,初始值为arr.length-1
int right = arr.length-1;
// 3.while循环查找,循环的条件:记录左边元素的索引 <= 记录右边元素的索引
while (left <= right){
// 4.计算中间元素的索引
int mid = (left + right) /2;
// 5.判断中间索引对应的元素与要查找的元素进行比较判断
if(arr[mid] == num){
// 6.如果中间索引对应的元素等于要查找的元素,那么就直接输出打印
return mid;
} else if(arr[mid] < num){
// 7.如果中间索引对应的元素 小于 要查找的元素,说明要查找的元素在右边,那么记录左边元素的索引就更改为 中间索引 +1(因为左侧不考虑)
left = mid + 1;
} else {
// 8.如果中间索引对应的元素 大于 要查找的元素,说明要查找的元素在左边,那么记录右边元素的索引就更改为 中间索引 -1(因为右侧不考虑)
right = mid -1;
}
}
return -1;
}
}