三大排序算法
排序算法 | 冒泡、选择、插入 |
冒泡排序
相邻的俩个元素比较,让值较大的数据逐渐向数组的底部(即朝最后一个元素)移动。
原理:比较两个相邻的元素,将值大的元素交换到右边。
public void sort(int[] a) {
for(int i=0;i<a.length-1;i++) {
for(int j=0;j<a.length-i-1;j++) {
if(a[j]>a[j+1]) {
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
选择排序
选择排序:每次从i的位置开始比到array.length-1,确定一个最小的数放到左边
1、确定循环次数:array.length-1次
for(int i=0;i<array.length-1;i++)
2、用index记录每次循环中最小数的下标,记录当前下标i
int index = i;
3、从当前位置(i)开始比到结尾,记录下最小的数的下标
for(int j=i+1;j<array.length;j++){
if(array[index]>array[j]){
index = j;
}
}
4、更换array[i]与array[index]的值。每次循环确定下标i的值。
public void select_sort(int[] a) {
System.out.println("排序前:" + Arrays.toString(a));
for (int i = 0; i < a.length - 1; i++) {
int index = i;// 默认为最小值下标(红色位置)
for (int j = i + 1; j < a.length; j++) {
// 找到最小值 最小值:j
if (a[index] > a[j]) {
index = j;
}
}
// 位置交换a[i]与a[index]
int temp = a[i];
a[i] = a[index];// 最小值移动到前面
a[index] = temp;// i位置上值移动到最小值位置
System.out.println("第" + (i + 1) + "趟" + Arrays.toString(a));
}
System.out.println("排序后:" + Arrays.toString(a));
}
插入排序
插入排序:假设数组部分有序,比如前3位有序。然后将无序的部分循环插入到已有序的序列中
1、确定循环次数,一个无序数组使用插入排序,每一位都要与前面有序的部分进行比较,
即第二位开始,与第一位比较(把第一位看成有序部分)
for(int i=0;i<array.length;i++)
2、记录当前数,即要插入的值temp 和 插入值的下标index;
int temp = array[i] int index = i;
3、循环遍历,当要插入的值小于前面的数array[j]时,需要将array[j]移动到array[j+1]的位置上。同时插入元素的位置会在前面。用index--表示
插入元素a[i]会移动到数组中的那个位置。
array[j + 1] = array[j];
index--;
4、遍历结束后将值a[i]插入空出来的位置index上
array[index] = temp;
// 插入排序
public void insert_sort(int[] a) {
System.out.println("排序前:" + Arrays.toString(a));
for (int i = 1; i < a.length; i++) {// 每次获取值:最后一个值(无序区间的最后一个值)
int index = i;// 插入的元素下标值
int temp = a[i];// 红色值(插入的元素值)
// 无序区间的第一个值与有序区间的每一个值进行比较。获取位置,进行组合
for (int j = i - 1; j >= 0; j--) {
// i-1:有序区间最后一位
// 比较:移动 提供插入位置
// j>=0:直到第一个元素结束
if (a[j] > temp) {// 移动位置
// 有序区间进行位置移动 覆盖之前的值:无序区间的第一个值位置
a[j + 1] = a[j];
index--;// 标识需要插入值的位置
}
}
// 插入数值
a[index] = temp;// 修改有序区间的元素值
System.out.println("第" + i + "趟:" + Arrays.toString(a));
}
System.out.println("排序后:"+Arrays.toString(a));
}
调用:
public static void main(String[] args) {
// TODO Auto-generated method stub
Test4 t = new Test4();
int[] a = { 3,1,5,2,8,7 };
t.insert_sort(a);
}
选择排序:a、每次把比较的第一个个数当做是最小数,如果找到后面有比自己小的数,就记录位置,比较完之后交换这两个数的位置。
b、选择排序的核心思想是每次比较时先假定参与比较的元素中最左边的为最小值,
然后拿这个 不一定是最小值(假定)的最小值与后面的各个元素比较,找到最小值,
并把最小值放到参与比较的元素的最左边。
选择排序以左边的最小值作为排序比较的出发点,其时间复杂度和冒泡排序相同,
但是选择排序交换的次数比冒泡排序少,选择排序的速度比冒泡快。
插入排序:a、(1)第一部分包含了这个数组的所有元素,但将最后一个元素除外,而第二部分就只包含这一个元素
(2)在第一部分排序后,再把这个最后元素插入到此刻已是有序的第一部分里的位置
b、插入排序的核心思想是局部有序,非局部有序的元素与局部有序的元素比较,并排
序,直到全部有序,这个过程局部有序序列不断变大。空间复杂度为O(n*n),
但是比冒泡和选择排序速度快
选择排序:每次从i的位置开始比到array.length-1,确定一个最小的数放到左边
1、确定循环次数:array.length-1次
for(int i=0;i<array.length-1;i++)
2、用index记录每次循环中最小数的下标,记录当前下标i
int index = i;
3、从当前位置(i)开始比到结尾,记录下最小的数的下标
for(int j=i+1;j<array.length;j++){
if(array[index]>array[j]){
index = j;
}
}
4、更换array[i]与array[index]的值。每次循环确定下标i的值。
插入排序:假设数组部分有序,比如前3位有序。然后将无序的部分循环插入到已有序的序列中
1、确定循环次数,一个无序数组使用插入排序,每一位都要与前面有序的部分进行比较,
即第二位开始,与第一位比较(把第一位看成有序部分)
for(int i=0;i<array.length;i++)
2、记录当前数,即要插入的值temp 和 插入值的下标index;
int temp = array[i] int index = i;
3、循环遍历,当要插入的值小于前面的数array[j]时,需要将array[j]移动到array[j+1]的位置上。同时插入元素的位置会在前面。用index--表示
插入元素a[i]会移动到数组中的那个位置。
array[j + 1] = array[j];
index--;
4、遍历结束后将值a[i]插入空出来的位置index上
array[index] = temp;
一、选择排序
public class Test{
public static void main(String[] args){
int[] array={10,17,45,8,75,24,44,11,7};
System.out.println("排序前的数组为:"+Arrays.toString(array));
for(int i=0;i<array.length-1;i++){
int index=i;//记录假最小值的下标
for(int j=i+1;j<array.length;j++){
if(array[index]>array[j]){
index=j;
}
}
//交换array[i]与array[index]元素位置
int temp=array[i];
array[i]=array[index];
array[index]=temp;
System.out.println("第"+(i+1)+"趟后数组为:"+Arrays.toString(array));
}
}
}
二、插入排序
import java.util.Arrays;
public class Test{
public static void main(String[] args){
int[] array = {34,8,64,51,32,21};
System.out.println("插入排序数组为:"+Arrays.toString(array));
for(int i=1;i<array.length;i++) {
int temp = array[i];//插入元素的值
int index=i;//插入元素的下标值
//array[i]与 它前面的元素(a[0]-a[i-1])进行比较。
for(int j=i-1;j>=0;j--) {
//当a[i]比前一个元素小,将前一个元素向后移动。
if (temp < array[j]) {
array[j + 1] = array[j];
index--;//插入元素下标值减小
}
}
//最后将a[0]-a[i-1]之间移动后空缺的位置array[index]插入a[i]
array[index] = temp;
System.out.println("第"+(i+1)+"趟后数组为:"+Arrays.toString(array));
}
}
}
扩展:
时间复杂度:
概念: 计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间。