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