冒泡排序和插入排序区别(小明版)
有一天小明上体育课,排的是3号位置,老师说:同学们请用冒泡排序的方法排好队。小明觉得自己比2号的小红高,所以互换位置,成为了2号。然后他觉得比1号小刚高,所以又互换位置排到了1号。老师说:小明,滚到最后去。最终他成了100号,这就是插入排序。
冒泡排序
算法原理
1. 比较相邻的两个元素,如果第一个比第二个元素大,则互换位置
2. 循环第一步操作;每重复一次,需要操作的元素个数减少一个,直到没有任何一个数字需要比较。
java代码:
void bubbleSort(int[] arr){
for(int i=1;i<arr.length;i++){
for(int j=0;j<arr.length-i;j++){
if(arr[j]>arr[j+1]){//此处代表升序排列
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1] = temp;
}
}
}
}
选择排序
算法原理
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
流程
1. 在一个长度为N的无序数组中,在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换
2. 遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换......至此选择排序完成。
java代码:
public static void sort(int[] arr){
if(arr == null || arr.length == 0){
return;
}
int minIndex=0;
int temp;
for(int i=0;i<arr.length;i++){
minIndex = i;//默认最小元素下标
for(int j=i+1;j<arr.length;j++){//找到最小元素
if(arr[j]<arr[minIndex]){
minIndex = j;//记录找到的最小元素的小标
}
}
if(minIndex != i){//如果记录的最小元素下标,跟默认的不一样,交换元素位置。
temp = arr[i];
arr[i]=arr[minIndex];
arr[minIndex] = temp;
}
}
}
插入排序
算法原理:
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。
流程:
1. 从第一个元素开始,该元素可以认为已经被排序
2. 取出下一个元素,在已经排序的元素列中从后向前扫描。如果该元素小于前面的元素,将前面元素后移 直到该元素等于或者大于前面元素为止,将该元素插入到当前位置;
3. 重复步骤2,到排序完成
java代码:
public static void insertSort(int[] numbers) {
int size = numbers.length;
int temp = 0;
int j = 0;
for (int i = 0; i < size; i++) {
temp = numbers[i];//要插入的元素值
for (j = i; j > 0 && temp < numbers[j - 1]; j--) {//假如temp比前面值大,不做處理
numbers[j] = numbers[j - 1];// 假如temp比前面的值小,则将前面的值后移
}
numbers[j] = temp;//此時的下標j即為要插入的位置。
}
}
快排
算法原理:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。
流程:
1. 设置两个变量i和j,i=0,j=arr.length-1;
2. 设置参考标准值,将原数组分为两个部分。此处我们将中间值作标准值;此时标准值元素下标(即参考下标,会随着排序的进行而发生变化)为: int mid = (i+j)/2;
3. 从下标i开始向后搜索,i++,保证元素值小于标准值;如果元素值比标准值大了,那么元素值赋给原标准值的位置即 arr[mid]=arr[i],此时,原参考下标由i取代。
4. 从下标j开始向前搜索,j--,保证元素值大于等于标准值;如果元素值比标准值小了,那么将元素值赋给此时的标准值位置 arr[mid]=arr[j],参考下标由j取代。
5. 重复3、4步骤,直到i=j;将标准值赋给此时的参考下标元素(arr[mid]=standard)。进行到这一步,数组标准值左边部分值都小于标准值;右边部分的值都是大于或者等于标准值的。
6. 左、右部分递归调用排序算法,完成整个数组的排序。
java代码:
public static void quickSort(int[]arr,int left,int right){//left为数组起始下标,right为结束下标
int mid = (left + right) / 2;//找到中间元素下标
int standard = arr[mid];//设置此下标对应值为标准值 。
int i = 0, j = 0;// 定义两个变量,用来接收left,right,保证left和right值不变,否则运用递归会导致下标越界
// 循环运算,最后结果 右边值都比标准值大,左边值都比标准值小
for (i = left, j = right; i < j;) {// 当i=j时就会跳出循环
while (i < mid && arr[i] < standard) {
i++;
}
if (i < mid) {// 此处有个隐含条件:一旦跳出上面的while循环,那么arr[i]的值肯定大于或者等于标准值
arr[mid] = arr[i];// 此时,原来下标i处的值已经取到了标准值位置
mid = i;
}
while (j > mid && arr[j] >= standard) {// 左半部分运算没考录与标准值相等的情况,右边部分应该考虑 全面。把与标准值相等的元素放到左半部分考虑亦可。
j--;
}
if (j > mid) {
arr[mid] = arr[j];
mid = j;
}
}
// 当运行到i=j时,跳出循环,此时 i,j,mid是重合的。把此处空出的值补上。
arr[mid] = standard;
// 递归调用
if (mid - left > 1) {// 至少剩下3个元素,两个元素没必要再进行排序。
quickSort(arr, left, mid - 1);// 左边部分
}
if (right - mid > 1) {
quickSort(arr, mid + 1, right);// 右半部分
}
}