public class SortDemoTest {
/**
* 日志
*/
private static final Logger logger = LoggerFactory.getLogger(SortDemoTest.class);
/**
* 快速排序
* 实现原理:在数据集之中,选择一个元素作为”基准”(pivot)。
* 所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。这个操作称为分区 (partition)。
* 操作,分区操作结束后,基准元素所处的位置就是最终排序后它的位置。
* 对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止
*
* 通过一趟排序将待排记录分割成独立的两部分,
* 其中一部分记录的关键字均比另一部分记录的关键字小,
* 则可分别对这两部分记录继续进行排序,已达到整个序列有序。
* 一趟快速排序的具体过程可描述为:从待排序列中任意选取一个记录(通常选取第一个记录)作为基准值,
* 然后将记录中关键字比它小的记录都安置在它的位置之前,将记录中关键字比它大的记录都安置在它的位置之后。
* 这样,以该基准值为分界线,将待排序列分成的两个子序列。
* 一趟快速排序的具体做法为:设置两个指针low和high分别指向待排序列的开始和结尾,记录下基准值baseval(待排序列的第一个记录),
* 然后先从high所指的位置向前搜索直到找到一个小于baseval的记录并互相交换,接着从low所指向的位置向后搜索直到找到一个大于baseval的记录并互相交换,
* 重复这两个步骤直到low=high为止。
* @param arr 数组
* @param lowIndex 数组开始索引
* @param highIndex 数组最后一个索引
*/
private static void quickSort (int[] arr,int lowIndex,int highIndex) {
//基准值
int key = arr[lowIndex];
//开始索引
int startIndex = lowIndex;
//末尾索引
int endIndex = highIndex;
//step 1.
//第一次循环找出基准值放在中间 左边的数小于基准值 右边的数大于基准值
while (endIndex>startIndex) {
//右边先移动
//最右边的值大于基准值向左移动
//endIndex>startIndex条件必须添加防止数组索引是负数
//arr[endIndex]>=key必须是>=要不然会出现死循环
while (endIndex>startIndex&&arr[endIndex]>=key) {
endIndex--;
}
//如果最右边的值小于定于基准值 进行调换位置
if(arr[endIndex]<=key) {
int temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
//之后左边在移动
//最左边的数小于基准值向右移动
//endIndex>startIndex条件必须添加防止数组索引是负数
//arr[startIndex]<=key必须是>=要不然会出现死循环
while (endIndex>startIndex&&arr[startIndex]<=key) {
startIndex++;
}
//如果最左边的数大于基准值 进行位置调换
if(arr[startIndex]>=key) {
int temp = arr[startIndex];
arr[startIndex] = arr[endIndex];
arr[endIndex] = temp;
}
}
//step 2.
//左边数组递归条件
if(startIndex>lowIndex) {
//基准左边的数组按照第一步去递归
quickSort(arr,lowIndex,startIndex-1);
}
//右边数组递归条件
if(endIndex<highIndex) {
//基准右边的数组按照第一步去递归
quickSort(arr,endIndex+1,highIndex);
}
}
/**
* 选择排序:
* 每一趟从待排序序列选择一个最小的元素放到已排好序序列的末尾,剩下的为待排序序列,
* 重复上述步骤直到完成排序。
* 5,18,22,9,11,13
* (5,18,22,9,11,13) 5 (5,18,22,9,11,13)
* (18,22,9,11,13) 9 (5,9,22,18,11,13)
* (22,18,11,13) 11 (5,9,11,18,22,13)
* (18,22,13) 13 (5,9,11,13,22,18)
* (22,18) 18 (5,9,11,13,18,22)
*
* 假设长度为n的数组arr,要按照从小到大排序,
* 那么先从n个数字中找到最小值min1,如果最小值min1的位置不在数组的最左端(也就是min1不等于arr[0]),
* 则将最小值min1和arr[0]交换,接着在剩下的n-1个数字中找到最小值min2,如果最小值min2不等于arr[1],
* 则交换这两个数字,依次类推,直到数组arr有序排列。
* 算法的时间复杂度为O(n^2)
* @param arr 数组
*/
private static void SelectSort(int[] arr) {
for (int i=0;i<arr.length;i++) {
for(int j=i+1;j<arr.length;j++) {
//假设第一个值是最小值,比最小值小你就是最小值了
if(arr[j]<arr[i]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j]=temp;
}
}
}
}
/**
* 冒泡排序
* 假设长度为n的数组arr,要按照从小到大排序。
* 则冒泡排序的具体过程可以描述为:首先从数组的第一个元素开始到数组最后一个元素为止,
* 对数组中相邻的两个元素进行比较,如果位于数组左端的元素大于数组右端的元素,
* 则交换这两个元素在数组中的位置,此时数组最右端的元素即为该数组中所有元素的最大值。
* 接着对该数组剩下的n-1个元素进行冒泡排序,直到整个数组有序排列。
* 算法的时间复杂度为O(n^2)。
* @param arr 数组
*/
private static void BubbleSort(int[] arr) {
for (int i = 0; i <arr.length ; i++) {
for (int j = 0; j+1 < arr.length-i; j++) {
if(arr[j+1]<arr[j]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1]= temp;
}
}
}
}
public static void main(String[] args) {
int[] arr = new int[]{6,1,2,7,7,9,3,9,4,5,10,8,6};
//quickSort(arr,0,arr.length-1);
//logger.info("快速排序数组 arr:{}",arr);
//SelectSort(arr);
//logger.info("选择排序数组 arr:{}",arr);
BubbleSort(arr);
logger.info("冒泡排序 arr:{}",arr);
}
}
在csdn 上看见的,为了面试自己看的,自己手写了三个排序方法