重新再再巩固了一遍排序,上次的排序整理也没有写全,但是上篇文章把思路给整理出来了,详细的想看的点击链接就好了
http://blog.csdn.net/anny_lin/article/details/47046191
下面是算法:
1.冒泡排序:
for(int i=0;i<a.length;i++)
{
for (int j = 1; j < a.length; j++)
{
int temp;
if (a[j]<a[i])
{
temp=a[j];
a[j]=a[i];
a[i]=temp;
}
}
2.选择排序:
/**
*
* 将i层循环每循环一次记录第一个元素的值(flag),然后再第二层循环中得到比flag
小的元素的值,付给a[i];,并记录下下标loc,第二层循环完成后获得最小元素下标,将flag
的值给予a[loc],完成交换
*
*/
for(int i=0;i<a.length;i++)
{
//记录循环第一个元素第一个
int flag=a[i];
//记录j层循环后最小元素的下标
int loc=i;
for(int j=i+1;j<a.length;j++)
{
if (a[j]<a[i]) {
a[i]=a[j];
loc=j;
}
}
a[loc]=flag;
}
3.插入排序:
将未排序的元素插入到已经排序完成的元素当中
for(int i=1;i<a.length;i++)
{
int temp=a[i];
int loc=i;
for(int j=i-1;j>=0;j--)
{
//记得跟a[j]比较的是temp,假设你写成a[i]就错了,a[i]的值是会变的
if (a[j]>temp)
{
a[j+1]=a[j];
loc=j;
}
}
a[loc]=temp;
}
4.归并排序:
public static int[] sort(int[] nums, int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
// 左边
sort(nums, low, mid);
// 右边
sort(nums, mid + 1, high);
// 左右归并
merge(nums, low, mid, high);
}
return nums;
}
public static void merge(int[] nums, int low, int mid, int high) {
int[] temp = new int[high - low + 1];
int i = low;// 左指针
int j = mid + 1;// 右指针
int k = 0;
// 把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = nums[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = nums[j++];
}
// 把新数组中的数覆盖nums数组
for (int k2 = 0; k2 < temp.length; k2++) {
nums[k2 + low] = temp[k2];
}
}
5.希尔排序:
static void shellSort( int[] a )
{
int group= a. length/2;
int j;
for(; group>=1; group/=2)
{
for( int i= group; i< a. length; i++)
{
int temp= a[ i];
for( j= i- group; j>=0&& a[ j]> temp; j-= group)
{
a[ j+ group]= a[ j];
}
a[ j+ group]= temp;
}
}
}
}
6.快速排序
static void sortDemo(int[] a,int begin,int end){
if (begin<end)
{
int i=quick_sort(a, begin, end);
sortDemo(a, begin, i-1);
sortDemo(a, i+1, end);
}
}
//进行基点的确定
static int quick_sort(int[] a,int begin,int end)
{
int x=a[begin];
int j=end;
int i=begin;
boolean flag=true;
while (i!=j)
{
if (flag)
{
//从右向左找到比x小的元素,进行填坑操作
for(;j>i;j--)
{
if (a[j]<x)
{
//填坑
a[i++]=a[j];
//只找一个数,break;跳出
flag=false;
break;
}
}
}else
{
//从左向右找到比x大的元素,进行填坑操作
for(;i<j;i++)
{
if (a[i]>x)
{
//填坑
a[j--]=a[i];
flag=true;
break;
}
}
}
}
a[i]=x;
return i;
}
7.堆排序:
//进行堆生成的关键步骤,即判断是否交换父节点与子节点的值
static void maxheap2(int[] a,int heapsize,int i)
{
//左节点
int left=2*i+1;
//右节点
int right=2*i+2;
//保存i的值
int large=i;
if (left<heapsize&&a[left]>a[i]) {
large=left;
}
//注意,进行比较的是a[right]>a[large],这样就能直接选出父节点下对应孩子节点最大的节点
if (right<heapsize&&a[right]>a[large]) {
large=right;
}
if (large!=i) {
//交换值
ArrayUtils.exchangeElements(a, i, large);
//进行递归,直到生成堆为止
maxheap2(a, heapsize, large);
}
}
//建立堆
static void bulidHeap(int[] a)
{
//从倒数第二排开始进行maxheap操作,当然从a.length-1开始也行,但是浪费不必要的时间
for (int i = a.length/2; i >=0; i--) {
maxheap2(a, a.length, i);
}
}
static void heapSort1(int[] a)
{
if (a.length<=1||a==null) {
return;
}
bulidHeap(a);
for (int i = a.length-1; i >=0; i--) {
//将堆顶元素与最后一个元素交换,同时数组大小将堆大小减一
ArrayUtils.exchangeElements(a, 0, i);
//重新生成堆
maxheap2(a, i, 0);
}
}
下面的过段时间给出,最近实习比较忙
8.基数排序:
来自百度百科
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
第一步
以LSD为例,假设原来有一串数值如下所示:
73, 22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
第二步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
81, 22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
第三步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
14, 22, 28, 39, 43, 55, 65, 73, 81, 93
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行分配,但在分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。
package num;
import java.util.Arrays;
import javax.activation.MailcapCommandMap;
public class Test {
public static void main(String[] args) {
int d=1;
int[] data = {56, 22, 101, 43, 55, 14, 28, 65, 39, 81, 33, 132};
d=getMaxd(data);
sort(data, d);
System.out.println(Arrays.toString(data));
}
public static void sort(int[] a,int d)
{
int k=0;
int n=1;
//表示依据哪一位数进行排序
int m=1;
//数组第一维表示可能的余数为0-9
int[][] array=new int[10][a.length];
//save数组表示位数是i的数的个数
int[] save=new int[10];
while (m<=d)
{
//将数字依次放入0-9的桶中
for(int i=0;i<a.length;i++)
{
int lsd=(a[i]/n)%10;
array[lsd][save[lsd]]=a[i];
save[lsd]++;
}
//重新排序
for (int i = 0; i < 10; i++)
{
//表示所代表的位数上的数组有值
if (save[i]!=0)
for(int j=0;j<save[i];j++)
{
a[k]=array[i][j];
k++;
}
//进行清零操作
save[i]=0;
}
m++;
k=0;
n*=10;
}
}
//获取数组中最大的位数
public static int getMaxd(int[] a)
{
int temp=a[0];
for(int i=0;i<a.length;i++)
{
if (temp<a[i]) {
temp=a[i];
}
}
int d=0;
while(temp>0)
{
temp/=10;
d++;
}
return d;
}
}
9.计数排序:
public static void main(String[] args) {
int d=1;
int[] data = {2,4,2,5,10,21,32,12,11,21,32,11,22,33};
countingSort(data, 33);
System.out.println(Arrays.toString(data));
}
public static void countingSort(int[] a ,int k) {
//k为最大的数
int[] temp=new int[k+1];
//依次将数字填入数组temp中,temp中的元素相当于排完顺序的
for(int i=0;i<a.length;i++)
{
temp[a[i]]++;
}
int x=0;
for(int i=0;i<k+1;i++)
{
while(temp[i]>0)
{
a[x]=i;
x++;
temp[i]--;
}
}
}
大功告成~