场景:输入一个数组,将数组进行排序。
(一)直接插入排序:
思想:
在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较, 所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较, 直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较, * 直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。
时间复杂度:O(n2) * 空间复杂度:O(1) * * 稳定性:稳定
有两层循环,外层循环是确定比较的数值,存入temp,第二层循环比较temp与数组inpu[j]的值.
如果temp小于inpu[j]的值,则inpu[j]后移到inpu[j+1],后移后,j--,然后继续比较temp与其inpu[j-1]的值,直至j=0;
但如果temp大于inpu[j]的值,则安排在inpu[j+1]上。
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int inpu[] = new int[n];
int i ;
//输入大小为n的数组
for(i=0;i<n;i++) {
inpu[i]=sc.nextInt();
}
//排序
for(i=1;i<n;i++) {
int temp=inpu[i];
int j =i-1;
for(;j>=0&&inpu[j]>temp;j--) {
inpu[j+1]=inpu[j];
}
inpu[j+1]=temp;
}
//输出排序后的数组
for( i =0;i<n;i++) {
System.out.print(inpu[i]+" ");
}
sc.close();
}
}
(二)冒泡排序:
基本思想:
第一趟起泡排序:
①首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换。
②然后比较第二个记录和第三个记录的关键字。依此类推,直至第n-1个记录和第n个记录的关键字进行过比较为止。
排序结果:关键字最大的记录被安置到最后一个记录的位置上
第二趟起泡排序:对前n-1个记录进行同样操作,其结果是使关键字次大的记录被安置到第n-1个记录的位置上。
* 时间复杂度:O(n2) * 空间复杂度:O(1) * * 稳定性:稳定排序
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int inpu[] = new int[n];
int i ;
//输入大小为n的数组
for(i=0;i<n;i++) {
inpu[i]=sc.nextInt();
}
//冒泡排序
//外层循坏确定扫描次数(n-1)次
for(i=0;i<inpu.length-1;i++) {
//内层循坏负责将大的元素浮到最后面
//每次扫描元素个数都将少一个
for(int j=0;j<inpu.length-i-1;j++) {
if(inpu[j]>inpu[j+1]) {
int temp =inpu[j];
inpu[j]=inpu[j+1];
inpu[j+1]=temp;
}
}
}
//输出排序后的数组
for( i =0;i<n;i++) {
System.out.print(inpu[i]+" ");
}
sc.close();
}
}
(三)简单选择排序
基本思想:在要排序的数组之中将第一最小值与数组第一个位置交换,然后在剩下的数组中,找出第二最小值,与第二位置交换,如此循环,直至数列全部有序。
* 时间复杂度:O(n2) * 空间复杂度:O(1) * * 稳定性:不稳定
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int inpu[] = new int[n];
int i ;
//输入大小为n的数组
for(i=0;i<n;i++) {
inpu[i]=sc.nextInt();
}
//简单选择排序
int position =0;
//外层循环确定有序序列
for(i =0;i<inpu.length;i++) {
position = i;
int temp =inpu[i];//暂且假设第一个元素为最小值
//内层确定无序序列
for(int j =i+1;j<inpu.length;j++) {//无序区中查找最小值
if(inpu[j]<temp) {
temp=inpu[j];//更新最小值
position =j;//记录最小值的位置
}
}
//将最小值的所在的位置与inpu[i]调换
inpu[position]=inpu[i];
inpu[i]=temp;
}
for( i =0;i<n;i++) {
System.out.print(inpu[i]+" ");
}
sc.close();
}
}
(四)快速排序
基本思想:在要排序的数组中找一个key,进行一趟排序后,所有比它小的元素排在它左边,比它大的元素排在它右边,利用递归的思想将其排好。
一趟排序的方法:
1,定义i=0,j=A.lenght-1,i为第一个数的下标,j为最后一个数下标
2,从数组的最后一个数Aj从右往左找,找到第一小于key的数,记为Aj;
3,从数组的第一个数Ai 从左往右找,找到第一个大于key的数,记为Ai;
4,交换Ai 和Aj
5,重复这个过程,直到 i=j
6,调整key的位置,把A[i]和key交换
时间复杂度:O(nlog2 n) * 空间复杂度:O(nlog2 n) * * 稳定性:不稳定
import java.util.Scanner;
public class Sort {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int inpu[] = new int[n];
int i;
for (i = 0; i < n; i++) {
inpu[i] = sc.nextInt();
}
sc.close();
QuickSort(inpu);
for (i = 0; i < n; i++) {
System.out.print(inpu[i] + " ");
}
}
public static void QuickSort(int a[]) {
if (a.length > 0) {
QuickSort(a, 0, a.length - 1);
}
}
public static void QuickSort(int a[], int low, int upper) {
// 递归算法的出口条件
if (low >= upper) {
return;
}
int i = low;
int j = upper;
int key = a[low];
while (i < j) {
while (i < j && a[j] > key) {
j--;// 从右侧找,找不见向前移
}
while (i < j && a[i] <= key) {
i++;// 从左测找,找不见向后移
}
if (i < j) {
// 找见了就交换两个的位置
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
// 将key与a[i]的位置交换
// 调整key的位置
int te = a[i];
a[i] = a[low];
a[low] = te;
// 对key左边的数进行快排
QuickSort(a, low, i - 1);
// 对key右边的数进行快排
QuickSort(a, i + 1, upper);
}
}