平时的工作中,如果遇到需要排序的问题,我们一般会直接使用Collections集合中提供的排序方法,简单实用。但是常用的排序算法我们也有必要自己理解消化,作为锻炼思维的一种方式,下面我把自己实现的常用算法写出来,供大家参考学习。支持纯数组排序,也支持任意实现了Comparable接口的类的排序,支持降序排序
package algorithm;
/**
* 排序器,包含了常用的排序方法
* @author wq
*
*/
public class Sorter {
/**
* 冒泡排序
* @param source 待排序数组
* @param desc 是否降序
* @return
*/
public static void bubleSort( int[] source ,boolean desc){
int temp = 0 ;
if(desc ){
for(int i = source. length - 1 ;i > 0; i--){
for(int j = 0; j < i; j++){
if(source [j ] < source[ j + 1]){
temp = source[j ];
source[j ] = source [j + 1 ];
source[j + 1 ] = temp ;
}
}
}
} else{
for(int i = source. length - 1 ;i > 0; i--){
for(int j = 0; j < i; j++){
if(source [j ] > source[ j + 1]){
temp = source[j ];
source[j ] = source [j + 1 ];
source[j + 1 ] = temp ;
}
}
}
}
}
/**
* 冒泡排序的泛型实现
* @param source
* @param desc
*/
public static <T extends Comparable <? super T>> void bubleSort(T [] source ,boolean desc){
T temp = null;
if(desc ){
for(int i = source. length - 1 ;i > 0; i--){
for(int j = 0; j < i; j++){
if(source [j ].compareTo (source [j + 1]) < 0 ){
temp = source[j ];
source[j ] = source [j + 1 ];
source[j + 1 ] = temp ;
}
}
}
} else{
for(int i = source. length - 1 ;i > 0; i--){
for(int j = 0; j < i; j++){
if(source [j ].compareTo (source [j + 1]) > 0 ){
temp = source[j ];
source[j ] = source [j + 1 ];
source[j + 1 ] = temp ;
}
}
}
}
}
/**
* 选择排序
* 算法思路:
* 从未排序序列中找出最大值/最小值,放入已排序序列的后面
* @param source 待排序数组
* @param desc 是否降序
*/
public static void selectionSort( int[] source,boolean desc ){
int minPos = 0 ;//记录最小值的索引
int maxPos = 0 ;//记录最大值的索引
int temp = 0 ;
if(desc ){
for(int i = 0; i < source.length -1 ;i ++){
maxPos = i ;
for(int j = i; j < source.length ;j ++){
if(source [j ] > source[ maxPos]){
maxPos = j ;
}
}
if(maxPos != i ){
temp = source[i ];
source[i ] = source [maxPos ];
source[maxPos ] = temp ;
}
}
} else{
for(int i = 0; i < source.length -1 ;i ++){
minPos = i ;
for(int j = i; j < source.length ;j ++){
if(source [j ] < source[ minPos]){
minPos = j ;
}
}
if(minPos != i ){
temp = source[i ];
source[i ] = source [minPos ];
source[minPos ] = temp ;
}
}
}
}
/**
* 选择排序的泛型实现
* @param source
* @param desc
*/
public static <T extends Comparable <? super T>> void selectionSort(T [] source ,boolean desc){
int minPos = 0 ;//记录最小值的索引
int maxPos = 0 ;//记录最大值的索引
T temp = null;
if(desc ){
for(int i = 0; i < source.length -1 ;i ++){
maxPos = i ;
for(int j = i; j < source.length ;j ++){
if(source [j ].compareTo (source [maxPos ]) > 0){
maxPos = j ;
}
}
if(maxPos != i ){
temp = source[i ];
source[i ] = source [maxPos ];
source[maxPos ] = temp ;
}
}
} else{
for(int i = 0; i < source.length -1 ;i ++){
minPos = i ;
for(int j = i; j < source.length ;j ++){
if(source [j ].compareTo (source [minPos ]) < 0){
minPos = j ;
}
}
if(minPos != i ){
temp = source[i ];
source[i ] = source [minPos ];
source[minPos ] = temp ;
}
}
}
}
/**
* 插入排序
* 算法思路:
* 1.假设数组的第一个元素为有序序列
* 2.取出下一个新元素,在已排序序列中从后向前比较,
* 3.如果当前元素大于新元素,将当前元素移到下一个位置
* 4.重复步骤3,直到当前元素小于新元素
* 5.将新元素插入到当前元素的后面
* 6.重复步骤2 -5
* @param source 待排序数组
* @param desc 是否降序
*/
public static void insertionSort( int[] source,boolean desc ){
int temp = 0 ;
if(desc ){
for(int i = 1; i < source.length ;i ++){
temp = source[i ];
int j = i - 1 ;
while(j >= 0 && source[j ] < temp){
source[j + 1 ] = source [j ];
j--;
}
if(j != (i - 1)){
source[j + 1 ] = temp ;
}
}
} else{
for(int i = 1; i < source.length ;i ++){
temp = source[i ];
int j = i - 1 ;
while(j >= 0 && source[j ] > temp){
source[j + 1 ] = source [j ];
j--;
}
if(j != (i - 1)){
source[j + 1 ] = temp ;
}
}
}
}
/**
* 插入排序的泛型实现
* @param source
* @param desc
*/
public static <T extends Comparable <? super T>> void insertionSort(T [] source ,boolean desc){
T temp = null;
if(desc ){
for(int i = 1; i < source.length ;i ++){
temp = source[i ];
int j = i - 1 ;
while(j >= 0 && source[j ].compareTo (temp ) < 0){
source[j + 1 ] = source [j ];
j--;
}
if(j != (i - 1)){
source[j + 1 ] = temp ;
}
}
} else{
for(int i = 1; i < source.length ;i ++){
temp = source[i ];
int j = i - 1 ;
while(j >= 0 && source[j ].compareTo (temp ) > 0){
source[j + 1 ] = source [j ];
j--;
}
if(j != (i - 1)){
source[j + 1 ] = temp ;
}
}
}
}
/**
* 快速排序
* @param source 待排序数组
* @param begin 数组起始索引
* @param end 数组结尾索引
*/
public static void quickSort( int[] source ,int begin,int end ,boolean desc){
int low = begin ;
int high = end ;
int middle = source [low ];//中轴数
if(desc ){
while(low < high){
//从后向前比较,如果发现比middle大的数,则放入low位置
while(low < high && source[high ] <= middle){
high--;
}
//刚开始的时候source[low]放在middle中,low位置相当于空位,
//后面的循环source[low]被放在high位置,low同样相当于空位
if(low < high){
source[low ] = source [high ];
}
//从前向后比较,如果发现比middle小的数,则放入high位置
while(low < high && source[low ] >= middle){
low++;
}
//source[high]已经被放入low位置,high相当于空位
if(low < high){
source[high ] = source [low ];
}
}
} else{
while(low < high){
//从后向前比较,如果发现比middle小的数,则放入low位置
while(low < high && source[high ] >= middle){
high--;
}
//刚开始的时候source[low]放在middle中,low位置相当于空位,
//后面的循环source[low]被放在high位置,low同样相当于空位
if(low < high){
source[low ] = source [high ];
}
//从前向后比较,如果发现比middle大的数,则放入high位置
while(low < high && source[low ] <= middle){
low++;
}
//source[high]已经被放入low位置,high相当于空位
if(low < high){
source[high ] = source [low ];
}
}
}
//循环完成之后low=high,再将中轴数middle放入
if(low == high ){
source[low ] = middle ;
}
if(low > begin){
quickSort(source ,begin ,low - 1 ,desc );
}
if(high < end){
quickSort(source , high + 1 ,end ,desc );
}
}
/**
* 快速排序的泛型实现
* @param source
* @param begin
* @param end
* @param desc
*/
public static <T extends Comparable <? super T>>
void quickSort(T [] source ,int begin, int end ,boolean desc){
int low = begin ;
int high = end ;
T middle = source [low ];//中轴数
if(desc ){
while(low < high){
//从后向前比较,如果发现比middle大的数,则放入low位置
while(low < high && source[high ].compareTo (middle ) <= 0){
high--;
}
//刚开始的时候source[low]放在middle中,low位置相当于空位,
//后面的循环source[low]被放在high位置,low同样相当于空位
if(low < high){
source[low ] = source [high ];
}
//从前向后比较,如果发现比middle小的数,则放入high位置
while(low < high && source[low ].compareTo (middle ) >= 0){
low++;
}
//source[high]已经被放入low位置,high相当于空位
if(low < high){
source[high ] = source [low ];
}
}
} else{
while(low < high){
//从后向前比较,如果发现比middle小的数,则放入low位置
while(low < high && source[high ].compareTo (middle ) >= 0){
high--;
}
//刚开始的时候source[low]放在middle中,low位置相当于空位,
//后面的循环source[low]被放在high位置,low同样相当于空位
if(low < high){
source[low ] = source [high ];
}
//从前向后比较,如果发现比middle大的数,则放入high位置
while(low < high && source[low ].compareTo (middle ) <= 0){
low++;
}
//source[high]已经被放入low位置,high相当于空位
if(low < high){
source[high ] = source [low ];
}
}
}
//循环完成之后low=high,再将中轴数middle放入
if(low == high ){
source[low ] = middle ;
}
if(low > begin){
quickSort(source ,begin ,low - 1 ,desc );
}
if(high < end){
quickSort(source , high + 1 ,end ,desc );
}
}
/**
* 快速排序
* @param source 待排序数组
* @param desc 是否降序
*/
public static void quickSort( int[] source ,boolean desc){
quickSort(source , 0 ,source .length - 1 , desc );
}
/**
* 快速排序的泛型实现
* @param source
* @param
*/
public static <T extends Comparable <? super T>> void quickSort(T [] source ,boolean desc){
quickSort(source , 0 ,source .length - 1 ,desc );
}
}