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;
}
}
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;
}
}
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;
}
}