估計大家一提到排序腦殼疼,連看都不想看,其實非也,簡單地排序並沒有你們想想的那麼難,接下來我就帶大家簡單用題目分析一下簡單排序的思想。
一、選擇排序
選擇排序(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();
}
}
未完待續········