一、冒泡排序
原理:比较两个相邻的元素,将值大(小)的元素排到最右端
思路:依次比较相邻的两个数,如果按照升序排列,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
时间复杂度:O(n^2)
举例说明:要排序数组:int[] a={6,3,8,2,9,1};
第一趟排序:
第一次排序:6和3比较,6大于3,交换位置: 3 6 8 2 9 1
第二次排序:6和8比较,6小于8,不交换位置:3 6 8 2 9 1
第三次排序:8和2比较,8大于2,交换位置: 3 6 2 8 9 1
第四次排序:8和9比较,8小于9,不交换位置:3 6 2 8 9 1
第五次排序:9和1比较:9大于1,交换位置: 3 6 2 8 1 9
第一趟总共进行了5次比较, 排序结果: 3 6 2 8 1 9
第二趟排序:
第一次排序:3和6比较,3小于6,不交换位置:3 6 2 8 1 9
第二次排序:6和2比较,6大于2,交换位置: 3 2 6 8 1 9
第三次排序:6和8比较,6大于8,不交换位置:3 2 6 8 1 9
第四次排序:8和1比较,8大于1,交换位置: 3 2 6 1 8 9
第二趟总共进行了4次比较, 排序结果: 3 2 6 1 8 9
第三趟排序:
第一次排序:3和2比较,3大于2,交换位置: 2 3 6 1 8 9
第二次排序:3和6比较,3小于6,不交换位置:2 3 6 1 8 9
第三次排序:6和1比较,6大于1,交换位置: 2 3 1 6 8 9
第三趟总共进行了3次比较, 排序结果: 2 3 1 6 8 9
第四趟排序:
第一次排序:2和3比较,2小于3,不交换位置:2 3 1 6 8 9
第二次排序:3和1比较,3大于1,交换位置: 2 1 3 6 8 9
第四趟总共进行了2次比较, 排序结果: 2 1 3 6 8 9
第五趟排序:
第一次排序:2和1比较,2大于1,交换位置: 1 2 3 6 8 9
第五趟总共进行了1次比较, 排序结果: 1 2 3 6 8 9
最终结果:1 2 3 6 8 9
代码实现:
public class maopao {
public static void main(String[] args) {
int[] a={6,3,8,2,9,1};
for(int i=1;i<a.length;i++){
//决定了比较的趟数
for(int j=0;j<a.length-i;j++){
//决定每一趟比较的次数
if(a[j]>a[j+1]){//决定是升序还是降序
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(int c=0;c<a.length;c++){
System.out.println(a[c]);
}
}
}
二、选择排序
原理:简单选择排序是最简单直观的一种算法,基本思想为每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。基于此思想的算法主要还有树型选择排序和堆排序。
思路:在算法实现时,每一趟确定最小元素的时候会通过不断地比较交换来使得首位置为当前最小,交换是个比较耗时的操作。其实我们很容易发现,在还未完全确定当前最小元素之前,这些交换都是无意义的。我们可以通过设置一个变量min,每一次比较仅存储较小元素的数组下标,当轮循环结束之后,那这个变量存储的就是当前最小元素的下标,此时再执行交换操作即可。
时间复杂度:O(n^2)
举例说明:要排序数组:int[] a={5,2,8,4,9,1};
第一趟排序: 原始数据:5 2 8 4 9 1
最小数据1,把1放在首位,也就是1和5互换位置,
排序结果:1 2 8 4 9 5
第二趟排序:
第1以外的数据{2 8 4 9 5}进行比较,2最小,
排序结果:1 2 8 4 9 5
第三趟排序:
除1、2以外的数据{8 4 9 5}进行比较,4最小,8和4交换
排序结果:1 2 4 8 9 5
第四趟排序:
除第1、2、4以外的其他数据{8 9 5}进行比较,5最小,8和5交换
排序结果:1 2 4 5 9 8
第五趟排序:
除第1、2、4、5以外的其他数据{9 8}进行比较,8最小,8和9交换
排序结果:1 2 4 5 8 9
代码实现:
public class jiandanxuanze {
public static void main(String[] args) {
int[] a={5,2,8,4,9,1};
for(int i=0;i<a.length-1;i++){
int min=i;
for(int j=i;j<a.length;j++){
if(a[min]>a[j]){
min=j;
}
if(min!=i){
swap(a,min,i);
}
}
}
for(int c=0;c<a.length;c++){
System.out.println(a[c]);
}
}
public static void swap(int []arr,int a,int b){
arr[a] = arr[a]+arr[b];
arr[b] = arr[a]-arr[b];
arr[a] = arr[a]-arr[b];
}
}
三、插入排序
原理:通过不断扩张有序序列的范围,对于未排序的数据,在已排序中从后向前扫描,找到相应的位置并插入。
思路:从第一个元素开始,该元素可以认为已经被排序
取出下一个元素,在已经排序的元素序列中从后向前扫描
如果该元素(已排序)大于新元素,将该元素移到下一位置
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
将新元素插入到该位置后
重复步骤2~5
时间复杂度:O(n^2)
举例说明:要排序数组:int[] a={12,4,5,2,6,14};
代码实现:
public class Sort {
public static void main(String[] args) {
int[] a={12,4,5,2,6,14};
insertsort(a);
System.out.println(Arrays.toString(a));
}
public static void insertsort(int []arr){
int i,j,node;
for(i=1;i<arr.length;i++){
node = arr[i];// 设置数组中的第2个元素为第一次循环要插入的数据
j = i - 1;
while (j >= 0 && node < arr[j]) {
arr[j + 1] = arr[j];// 如果要插入的元素小于第j个元素,就将第j个元素向后移动
j--;
}
arr[j + 1] = node;// 直到要插入的元素不小于第j个元素,将node插入到数组中
}
}
}