常見排序算法


1.冒泡排序

import java.util.*;
public class BubbleSort {
    public int[] bubbleSort(int[] A, int n) {
       /*
       1.A[0]~A[n-1]進行比較,A[0]與A[1]進行比較,較大的爲A[1],A[1]與A[1]進行比較,較大的爲A[2].......A[n-2]與A[n-1]
       進行比較,較大爲A[n-1]。這樣最大的數爲A[n-1].
       2.A[0]~A[n-2]進行比較,過程與步驟1相同,這樣倒數第二大的數爲A[n-2]
       .........
       3.A[0]與A[1]進行比較,較大數爲A[1].
       */
        int temp=0;
        for(int i=n-1;i>=1;i--)
            for(int j=0;j<i;j++)
            {
            if(A[j]>A[j+1])
                {
                temp=A[j];
                A[j]=A[j+1];
                A[j+1]=temp;
            }
         }
        return A;
    }
}


2.選擇排序

import java.util.*;
public class SelectionSort {
    public int[] selectionSort(int[] A, int n) {
        /*
        1.A[0]依次與A[i](1=<i<=n-1)進行比較,較小值放在A[0],最後A[0]爲最小值
        2.A[1]依次與A[i](2=<i<=n-1)進行比較,較小值放在A[1],最後A[1]爲第二小值
        ......
        3.A[n-2]與A[n-1]進行比較,較小值放在A[n-2],那麼A[n-2]爲第二大值,A[n-1]爲最大值。
        */
        for(int i=0;i<n-1;i++)
            for(int j=i+1;j<=n-1;j++)
            {
            if(A[i]>A[j])
                {
                int temp=A[i];
                A[i]=A[j];
                A[j]=temp;
            }
        }
        return A;
    }
}

3.插入排序

import java.util.*;

public class InsertionSort {
    public int[] insertionSort(int[] A, int n) {
       /*
       1.A[1]與A[0]進行比較,較大者爲A[1]
       2.A[2]與(A[0],A[1])進行比較,將A[2]放入合適位置,即A[2]前邊的數比A[2]小,A[2]後邊的數比A[2]大。
       ........
       3.A[n-1]與(A[0].....A[n-2])進行比較,將其放入合適位置
       */
        for(int i=1;i<=n-1;i++)
            {
            for(int j=0;j<i;j++)
                {
                if(A[i]<A[j])
                    {
                    int temp=A[i];
                    A[i]=A[j];
                    A[j]=temp;
                }
            }
        }
        return A;
    }
}


4.歸併排序

import java.util.*;
public class MergeSort {
    public int[] mergeSort(int[] A, int n) {
        /*
        1.將A分成有2個數的區間,每個區間內進行排序
        2.將排序好的區間兩兩合併,成爲有4個數的區間,每個區間內排序
        3.排序好的區間兩兩合併,成爲有8個數的區間,每個區間內排序
        .......
        4.最終成爲1個有序的區間。
        //由上可以看出,主要分2個過程,1個是排序,1個是合併。排序是用遞歸實現的,是一點點縮小範圍的。在合併裏纔會排序。
        */
        sort(A,0,n-1);
        return A;
    }
    public void merge(int[] A,int left,int mid,int right)
        {
        //把A[left....mid]與A[mid+1.....right]合併
        int[] temp=new int[right-left+1];//定義一個數組用來放合併後的數字
        int i=0;//temp數組的下標起始值
        int j=left;//A[left....mid]的起始下標
        int m=mid+1;//A[mid+1.....right]的起始下標
        while(j<=mid&&m<=right)//要合併的兩個數組都存在的情況
            {
            if(A[j]<A[m])
                {
                temp[i++]=A[j++];
            }
            else
                {
                temp[i++]=A[m++];
            }
        }
        while(j<=mid)//左半邊長
            {
            temp[i++]=A[j++];
        }
        while(m<=right)//右半邊長
            {<pre name="code" class="java">import java.util.*;
public class QuickSort {
    public int[] quickSort(int[] A, int n) {
       /*
       隨機找到一個數,比這個數小的在左邊,比這個數大的在右邊,然後左右兩邊分別採用快速遍歷。
       一個快排的過程:
       1.i=0;j=n-1,隨機選取的數key,通常選A[0]=key
       2.j從右往左遍歷,如果A[j]<key,那麼交換A[i],A[j],否則j--
       3.i從左往右遍歷,如果A[i]>key,交換A[i],A[j],否則i++
       4.重複步驟2,3,直至i=j.此時需要返回i的位置,爲下次快排提拱分邊依據
       */
        quick(A,0,n-1);
        return A;
    }
    public int sort(int[] A,int left,int right)//一次快排的過程
        {
        int i=left;
        int j=right;
        int key=A[left];
        while(i<j)
            {
          while(i<j&&A[j]>=key)//只能用while因爲要找到第一個比key的值之前j要一直--。
              {
              j--;
          }
            if(i<j)
                {
                int temp=A[j];
                A[j]=A[i];
                A[i]=temp;
                i++;//現在A[i]一定比key小,沒有必要再比較了,所以i++
            }
            while(i<j&&A[i]<=key)
                {
                i++;
            }
            if(i<j)
                {
                int temp=A[i];
                A[i]=A[j];
                A[j]=temp;
                j--;//現在A[j]一定比key大,沒有必要再比較了,所以j--
            }
        } 
        return i;
    }
    public void quick(int[] A,int left,int right)
        {
        while(left<right)
            {
            int m=sort(A,left,right);
            quick(A,left,m-1);
            quick(A,m+1,right);
        }
    }
}


5.快速排序

import java.util.*;
public class QuickSort {
    public int[] quickSort(int[] A, int n) {
    /*
      隨機找到一個數,比這個數小的在左邊,比這個數大的在右邊,然後左右兩邊分別採用快速遍歷。
       一個快排的過程:
       1.i=0;j=n-1,隨機選取的數key,通常選A[i]=key(想當於挖了個坑)
       2.j從右往左遍歷,如果A[j]>=key,j--,否則A[i]=A[j](注意是A[i]不是A[left],因爲第一次填坑是A[left],
       下一個比key大的數就是填的A[i]的坑的);
       3.i從左往右遍歷,如果A[i]<=key,i++,否則A[j]=A[i]
       4.重複步驟2,3,直至i=j,最後將A[i]=key。
    */
       quick(A,0,n-1);
        return A;
 }
    public int sort(int[]A,int left,int right)
        {
            int i=left;
            int j=right;
            int key=A[i];
        if(left<right)
            {
           
            while(i<j)//循環的條件:i<j,在循環的過程中可能會出現i>j的情況,所以下面代碼段要判斷i<j
                {
                while(i<j&&A[j]>=key)
                {
                    j--;
                }
                if(i<j) 
                {
                    A[i]=A[j];
                    i++;//現在A[i]一定比key小,沒有必要再比較了,所以i++
                }
                while(i<j&&A[i]<=key)
                    {
                    i++;
                }
               if(i<j) 
               {
                   A[j]=A[i];
                   j--;
               }
                
            }
            A[i]=key;
        }
         return i;
    }
    public void quick(int[]A,int low,int high)
        {
        
       if(low<high)
            {
               int m=sort(A,low,high);
               quick(A,low,m-1);
               quick(A,m+1,high);
            
        }
    }
}

6.堆排序


import java.util.*;

public class HeapSort {
    public int[] heapSort(int[] A, int n) {
        // write code here
        //建堆
        A=build(A,n);
        //交換順序然後調整
        for(int i=n-1;i>0;i--)
            {
            int temp=A[0];
            A[0]=A[i];
            A[i]=temp;
            adjust(A,0,i);
        }
        return A;
    }
       //調整堆
    public void adjust(int []a,int i,int n)
        {
        int temp=a[i];
        int j=2*i+1;//i的左孩子
        while(j<n)
            {
            if(j+1<n&&a[j]<a[j+1])//右孩子大,則j爲右孩子,j+1<n很關鍵,不然會出錯,//因爲要比較左右孩子必須有右孩子
            {
                j++;
            }
            if(temp>a[j])//根節點大,則不變
                {
                  break;
              }
            else//根節點小
            {
                a[i]=a[j];//那麼就把a[j]的值賦給a[i]
                i=j;//i到j的位置
                j=2*i+1;//j爲i的左孩子
                
            }
            
            a[i]=temp;//現a[i]位置爲temp
        }
       
    }    
    //建大根堆
    public int[] build(int []a,int n)
        {
        for(int i=n/2;i>=0;i--)//第一個非葉子節點是n/2
            {
            adjust(a,i,n);
        }
        return a;
    }
}
7.希爾排序
</pre><pre name="code" class="java">
<pre name="code" class="java">import java.util.*;
public class ShellSort {
    public int[] shellSort(int[] A, int n) {
      /*
      是插入排序的變形,步長數可以改變,步長爲k,那前k個不用比較,A[k]與A[0]比,A[k+1]與A[1]比...值得注意的
      是A[m]與A[m-k]比較,如果A[m]<A[m-k],需要交換位置,然後A[m-k]繼續與A[m-2k]比較....直至到m>=feet
      */
        int feet=n/2;
            while(feet>0)
                {
               for(int i=feet;i<=n-1;i++)
            { 
                int m=i;
                   while(m>=feet)//m從i開始的,m與m-feet比較,m最小爲feet,此時m-feet爲0
                       {
                       if(A[m]<A[m-feet])//交換位置
                           {
                        int temp =A[m];
                           A[m]=A[m-feet];
                           A[m-feet]=temp;
                    }
                       m=m-feet;//m往前走
                }
            }
                feet=feet/2;
        }
        return A;
    }
}



8.計數排序

import java.util.*;
public class CountingSort {
    public int[] countingSort(int[] A, int n) {
      /*
      找到A的最大值max和最小值min,然後生成max-min+1個桶,將A-min的個數放入桶中,然後按桶的順序依次將數取出,得到排序好的
      數,注意的是一個桶中可能有多個數
      */ 
        int min=A[0];
        int max=A[0];
        for(int i=0;i<n;i++)
            {
            if(A[i]<min)
                min=A[i];
            if(A[i]>max)
                max=A[i];
        }
        int[] bucket=new int[max-min+1];
        //放數(bucket下標對應A[i]-min,值爲個數)
        for(int i=0;i<n;i++)
            {
          bucket[A[i]-min]++;
        }
        //輸出內容
        int index=0;//A的下標
        for(int i=0;i<max-min+1;i++)//桶的個數
            for(int j=0;j<bucket[i];j++)//桶裏的個數
            {
            A[index++]=i+min;
        }
        return A;
    }
}


9.基數排序

import java.util.*;
public class RadixSort {
    public int[] radixSort(int[] A, int n) {
       /*
       基數排序是按一個二維數組的桶,行是10,表示0~9的餘數,列是n表示每個桶裏可能放n個數。以個位進行排序,將餘數相同的放入
       一個桶中。桶中放的是數,需要一個數組來記錄每個餘數有幾個數。然後以十位,百位...進行排序
       */
        if(A==null||n<2)
            return A;
        int[][] bucket=new int[10][n];//10表示餘數爲0~9,n表示餘數爲某個值的桶裏可能有n個值
        int a=1;//除數
        int m=1;//位數
        int index=0;//A的下標
        int []count=new int[10];//記錄餘數爲某個數時的個數
            while(m<=4)//所以元素小於等於2000,最多有4位
            {
             //桶中放數
        for(int i=0;i<A.length;i++)
            {
            int p=(A[i]/a)%10;//餘數
            bucket[p][count[p]]=A[i];//將A[i]放入bucket[p][count[p]]中
            count[p]++;//餘數爲p的個數加1,相當於是bucket[p]的列號
        }
            //從桶中倒數
            for(int i=0;i<10;i++)
                {
                if(count[i]!=0)//有數才能往外倒
                    {
                    for(int j=0;j<count[i];j++)
                        {
                        A[index++]=bucket[i][j];
                    }
                }
                count[i]=0;//清空桶,就是把餘數爲i的個數設爲0,從頭開始放數。
            }
            a=a*10;
            m++;
            index=0;//每次倒數都是從新開始的
        }
        return A;
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章