java排序二

重新再再巩固了一遍排序,上次的排序整理也没有写全,但是上篇文章把思路给整理出来了,详细的想看的点击链接就好了
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]--;
            }
        }
    }

大功告成~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值