八大排序算法代码实现(java)



import javax.xml.crypto.Data;
import java.sql.Array;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.SimpleTimeZone;

public class 排序 {
    public static void main(String[] args) {
        int arr[]={3,9,-1,10,6,20};
        System.out.println(Arrays.toString(arr));
        selectSort(arr);
    }
    public static void BubbleSort(int arr[])//从前往后大数冒泡到后边
    {
        int t=0;
        boolean flag=false;
        for(int i=0;i<arr.length-1;i++)//控制一共排序了n-1趟
        {
            for (int j=0;j<arr.length-1-i;j++)//真正起作用排序的循环,只排序一趟,每次排序都是比较n-1躺,因为两两结合是n-1次
            {
                if(arr[j]>arr[j+1])
                {
                    flag=true;
                    t=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=t;
                }
            }
            System.out.println("第"+(i+1)+"次排序后的数组");
            System.out.println(Arrays.toString(arr));
            //优化
//            if(!flag)
//            break;
//            else
//            flag=false;
        }
    }
    public static void selectSort(int arr[])
    {
        for(int i=0;i<arr.length-1;i++)//一共比较n-1次
        {
            int minIndex=i;//第一次是0,1,2,3,因为从先把第一个排好不管接着下一个,完全符合外循环
            int min=arr[i];
            for(int j=i+1;j<arr.length;j++)
            {
                if(min>arr[j])
                {
                    min=arr[j];
                    minIndex=j;
                }
            }
            //优化,看是否用交换
            if(minIndex!=i)
            {
                arr[minIndex]=arr[i];
                arr[i]=min;
            }
            System.out.println("第"+(i+1)+"次交换后");
            System.out.println(Arrays.toString(arr));
        }

    }
    public static void insertSort(int arr[])
    {
        for(int i=1;i< arr.length;i++)//设计十分巧妙,直接从第二个人数据开始比较,而且比较了n-1趟
        {
            int insertVal=arr[i];
            int insetIndex=i-1;
            while(insetIndex>=0&&insertVal<arr[insetIndex])//两个有一个条件不符合就退出,
                // 第一个情况是该插入可能是最小的,第二种情况是插入的在中间部分
            {
                arr[insetIndex+1]=arr[insetIndex];//往后移
                insetIndex--;//一直向前比较和且往后移动,给插入的最小值挪位置
            }
            //优化
            if(insetIndex+1!=i)
            {
                arr[insetIndex+1]=insertVal;//在循环外已经标记好了
            }
//            System.out.println("第"+i+"轮排序后");
//            System.out.println(Arrays.toString(arr));
        }
    }
    public static void shellSort(int[] arr)//交换法
    {
        int temp=0;
        int count=0;
        for(int gap=arr.length/2;gap>0;gap/=2)//分成若干个小组
        {
            for(int i=gap;i<arr.length;i++)//每个小组倒着记录
            {
                for(int j=i-gap;j>=0;j-=gap)//该循环用来寻找可以匹配的小组
                {//随着组数的减少,匹配符合的小组次数增加,循环比较会越来越多
                    if(arr[j]>arr[j+gap])
                    {
                        temp=arr[j];
                        arr[j]=arr[j+gap];
                        arr[j+gap]=temp;
                    }
                }
            }
           // System.out.println("希尔排序第"+(++count)+"轮: "+arr.toString());
        }

    }
    public static void shell2Sort(int[] arr)//移位法
    {
        for(int gap=arr.length/2;gap>0;gap/=2)
        {
            //从第gap个开始,对其所在的组进行直接插入排序
            for(int i=gap;i<arr.length;i++)
            {
                int j=i;
                int temp=arr[j];
                if(arr[j]<arr[j-gap])
                {
                    while(j-gap>=0&&temp<arr[j-gap])
                    {
                        arr[j]=arr[j-gap];
                        j-=gap;
                    }
                    //当退出while循环后,就给temp找到了合适的插入位置
                    arr[j]=temp;
                }
            }
        }
    }
    public  static void  quickSort(int[] arr,int left,int right )
    {
        int l=left;
        int r=right;
        int pivot =arr[(left+right)/2];
        int temp=0;
        //完成左边都是小的,右边都是大的
        while(l<r)
        {
            while (arr[l]<pivot)
            {
                l+=1;
            }
            while (arr[r]>pivot)
            {
                r-=1;
            }
            //如果成立,说明已经排好
            if(l>=r)
                break;
            //不满足交换
            temp=arr[l];
            arr[l]=arr[r];
            arr[r]=temp;
            //交换完发现arr[l]=pivor,前移
            if(arr[l]==pivot)
                r-=1;
            if(arr[r]==pivot)
                l+=1;
        }
        //不处理这个会栈溢出
        if(l==r)
        {
            l+=1;
            r-=1;
        }
        //向左递归
        if(left<r)
        {
            quickSort(arr,left,r);
        }
        if(right>l)
        {
            quickSort(arr,l,right);
        }
    }
   public static void merge(int arr[],int left,int mid,int right,int temp[])
   {
       int i=left;
       int j=mid+1;
       int t=0;
       while(i<mid&&j<right)
       {
           if(arr[i]<arr[j])
           {
               temp[t]=arr[i];
               t+=1;
               i++;
           }
           else
           {
               temp[t]=arr[j];
               t++;
               j++;
           }
       }
       while (i<mid)
       {
           temp[t]=arr[i];
           t++;
           i++;
       }
       while (j<left)
       {
           temp[t]=arr[j];
           t++;
           j++;
       }
       //拷贝
       t=0;
       int tempLeft=left;
       while(tempLeft<=right)//跟着递归走的
       {
           arr[tempLeft]=temp[t];
           t++;
           tempLeft++;
       }
   }
   public static void mergeSort(int arr[],int left,int right,int temp[])
   {
       if(left<right)
       {
           int mid=(left+right)/2;
           //左递归
           mergeSort(arr,left,mid,temp);
           //右递归
           mergeSort(arr,mid+1,right,temp);
       }
   }
   public static void radixSort(int arr[])//耗费格外多的内存,但是很稳定(对于相同大小的数据,排序后两者顺序不确定则不稳定,顺序确定则稳定
           //对于有负数的尽量不要用,因为取模后会有负值下标,导致数组越界,改进办法是取模时取绝对值,去除的时候再反转
   {
       int max=arr[0];
       for(int i=1;i<arr.length;i++)
       {
           if(arr[i]>max)
               max=arr[i];
       }
       int maxLength=(max+"").length();//求数组的位数!!!超级nice巧妙!!
       int bucket[][]=new int[10][arr.length];
       int bucketElementsCounts[]=new int[10];//记录每个桶的元素个数
       for(int i=0,n=1;i<maxLength;i++,n*=10)
       {
           for (int j=0;j<arr.length;j++)
           {
               int digitOfElement=arr[i]/n%10;
               bucket[digitOfElement][bucketElementsCounts[digitOfElement]]=arr[j];
               bucketElementsCounts[digitOfElement]++;//记录后个数要加一
           }
           //按照这个顺序放到原来的数组
           int index=0;
           for(int k=0;k<bucketElementsCounts.length;k++)
           {
               if(bucketElementsCounts[k]!=0)
               {
                   for(int l=0;l<bucketElementsCounts[k];l++)
                   {
                       arr[index++]=bucket[k][l];
                   }
               }
               bucketElementsCounts[k]=0;//清0
           }
       }
   }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值