估计大家一提到排序脑壳疼,连看都不想看,其实非也,简单地排序并没有你们想想的那么难,接下来我就带大家简单用题目分析一下简单排序的思想。
一、选择排序
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。例:
选择排序的流程图:
选择排序的代码实现:
class Test02{
public static void main(String[] args){
int[] arr1=new int[]{1,3,2,7,4,6,8,5,9};
int temp=0;
/*
选择排序————具体通过一组数据来说明什么是选择排序?定义一个一位数组
a[]={1,3,2,7,4,6,8,5,9};
要求是:按升序排列
数组的下标: 0 1 2 3 4 5 6 7 8
1 3 2 7 4 6 8 5 9
首先先具体分析一下整个选择的过程:
第一次:
数组的下标: 0 1 2 3 4 5 6 7 8
1 3 2 7 4 6 8 5 9
首先是数组中a[0]与a[1]先比较,如果大于,两个数字交换,否则进行a[0]与a[2]比较
,如果大于,两个数交换,否则继续,以此类推,因此第一次比较的结果为:
1 3 2 7 4 6 8 5 9
第二次:
首先是数组中a[1]与a[2]比较,如果大于,两个数交换,否则进行a[1]与a[3]比较,
如果大于,两个数进行交换,否则继续,以此类推,因此第三次比较的结果为:
1 2 3 7 4 6 8 5 9
第三次:1 2 3 7 4 6 8 5 9
第四次:1 2 3 4 7 6 8 5 9
第五次:1 2 3 4 5 7 8 6 9
第六次:1 2 3 4 5 6 8 7 9
第七次:1 2 3 4 5 6 7 8 9
第八次:1 2 3 4 5 6 7 8 9
整个过程就是选择排序。
*/
for(int i=0;i<arr1.length-1;i++){
for(int j=i+1;j<arr1.length;j++){
if(arr1[i]>arr1[j]){
temp=arr1[i];
arr1[i]=arr1[j];
arr1[j]=temp;
}
}
}
System.out.print("选择排序:");
for(int i=0;i<arr1.length;i++){
System.out.print(arr1[i]+" ");
}
System.out.println();
}
}
二、冒泡排序
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。例:
冒泡排序的流程图:
冒泡排序的代码实现以及对冒泡排序的优化:
class Test02{
public static void main(String[] args){
int[] arr2=new int[]{1,3,2,7,4,6,8,5,9};
int[] arr3=new int[]{1,3,2,7,4,6,8,5,9};
int temp=0;
maoPao(arr2);
youHua(arr3);
}
/*
冒泡排序————例:给定一组数据——要求升序
2 4 3 8 6 9 7
第一次:
第一步:首先判断给定数据的前两个数值:2和4的大小,如果前者大于后者,则前者与后者交换位置,否则,不用
2 4 3 8 6 9 7
第二步:在第一步的基础上判断第二个和第三个数值的大小,如果前者大于后者,则前者与后者交换位置,否则,不用
2 3 4 8 6 9 7
第三步:2 3 4 8 6 9 7
第四步:2 3 4 6 8 9 7
以此类推
因此第一步所得的结果为:2 3 4 6 8 7 9
第二次所得结果:2 3 4 6 7 8 9
以此类推
最终结果为:2 3 4 6 7 8 9
以上就是冒泡排序的这个过程
*/
public static void maoPao(int[] arr){
int temp=0;
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.print("冒泡排序:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
/*
冒泡排序的优化——例:给定一组数据——要求升序
2 4 3 8 6 9 7
由上面可知,如果这组数据中最大的数字位于该数据的首位,岂不是得比较该数据长度-1次
而且在每一次比较的时候都得需要交换两个数值,因此为了避免多次交换,引入一个存放数值的变量temp;
具体思路以及解题过程如下:
第一次:2 3 4 6 8 7 9
第一步:先把该数据的第一个元素存放到temp中,temp=2;接着再判断temp的值与该数据第二个元素的大小
,如果大于,则前移,如果小于,把temp赋值给该数值的前一位,再把该数据中比temp值大的数赋值给temp,
以此类推
第二次:2 3 4 6 7 8 9
*/
public static void youHua(int[] arr){
int temp=0;
for(int i=0;i<arr.length-1;i++){
temp=arr[0];
for(int j=0;j<arr.length-i-1;j++){
if(temp>arr[j+1]){
arr[j]=arr[j+1];
}
else{
arr[j]=temp;
temp=arr[j+1];
}
}
arr[arr.length-i-1]=temp;
}
System.out.print("冒泡排序的优化:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
三、插入排序
插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到
的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
插入排序的流程图:
动图演示:
插入排序代码实现:
class Test02{
public static void main(String[] args){
int[] arr4=new int[]{1,3,2,7,4,6,8,5,9};
int temp=0;
chaRu(arr4);
}
/*
插入排序——例:给定一组数据——要求升序
2 4 3 8 6 9 7
插入排序的本质也是交换两个数值,插入排序,首先是从一组数据中第二个元素开始,之后每一从后面去一个
元素,放到前面一个合适的位置,因此称之为插入。
第一步:先是从一组数据中的第二个元素开始进行;
第二步:开始第二个元素与第一个元素比较,如果前者大于后者,则前者与后者交换位置,否则,不用
因此所得结果:2 4 3 8 6 9 7
以此类推
第三步:2 3 4 8 6 9 7
第四步:2 3 4 8 6 9 7
第五步:2 3 4 6 8 9 7
第六步:2 3 4 6 8 9 7
第七步:2 3 4 6 8 7 9
因此以上就是插入排序的整个过程
*/
public static void chaRu(int[] arr){
int temp=0;
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j>=1;j--){
if(arr[j]<arr[j-1]){
temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}
}
}
System.out.print("插入排序:");
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
四、计数排序
计数排序(Counting sort)是一种稳定的线性时间排序算法。计数排序使用一个额外的数组,其中第i个元素是待排序数组中值等于的元素的个数。然后根据数组来将中的元素排到正确的位置
动图演示:
计数排序的代码实现:
import java.util.Scanner;
class Demo01_02{
public static void main(String[] args){
Scanner input=new Scanner(System.in);
System.out.print("Enter a nums:");
int[] arr=new int[0];
while(true){
int num=input.nextInt();
if(num==0){
break;
}
arr=copyOf(arr);
arr[arr.length-1]=num;
}
/*
计数排序——1、计数排序就是首先申请一篇与给定数据的最大值与最小值的差加一同大小的空间
2、然后遍历给定的数据,把一个数据存放在与之该数据的值减去最小值得到的结果,
然后把该结果与所申请空间的下标对应起来,即该下标所对应的值加一
3、因为所申请的数组大小并没有赋值,因此,该下标所对应的值都为0
下面通过一组数据说明问题:
给定的数据:1 2 5 3 4 3 -2 -2 2
1、首先先确定该数组的最大值max与最小值min——max=5;min=-2
2、确定所要申请数组的空间大小:max-min+1=8
3、标记新数组的下标:
0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
4、遍历该数组:
1 2 5 3 4 3 -2 -2 2
第一个元素:1——所对应的下标为:1-min=3
因此在第三步中对应下标3中所存的数字加一
第二个元素:2——所对应的下标为:2-min=4
因此在第三步中对应下标4中所存的数字加一
以此类推
*/
int min=arr[0];
int max=0;
int offest=0;
for(int i=0;i<arr.length;i++){
if(arr[i]>max){
max=arr[i];
}
if(arr[i]<min){
min=arr[i];
}
}
int[] newArr=new int[max-min+1];
for(int i=0;i<arr.length;i++){
newArr[arr[i]-min]++;
}
/*
输出语句
*/
show(arr,newArr);
}
public static int[] copyOf(int[] arr){
int[] newArr=new int[arr.length+1];
for(int i=0;i<arr.length;i++){
newArr[i]=arr[i];
}
return newArr;
}
public static void show(int[] arr,int[] newArr){
int min=arr[0];
for(int i=0;i<arr.length;i++){
if(arr[i]<min){
min=arr[i];
}
}
for(int i=0;i<newArr.length;i++){
for(int j=1;j<=newArr[i];j++){
System.out.print((i+min)+" ");
}
}
System.out.println();
}
}
未完待续········