常见排序算法


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


2.选择排序

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


4.归并排序

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值