1、快速排序
package algorithm;
import java.util.Random;
/**
* 快速排序:
* 取第一个数 a 作为基准元素,将数组分成三部分,比a小的元素放到一个数组里面,比a大的放到一个数组里面,再分别对这两个数组进行快排
* 时间复杂度:O(nlogn)
* 不稳定
* 随机快排:
* 随机取一个元素作为基准元素,避免了极端的情况(比如其他元素都比第一个元素大或者小,最极端的情况会变成选择排序,复杂度为O(n^2))
* 时间复杂度:O(nlogn)
* 以下是基于随机快排实现
*/
public class QuickSort {
static int sum = 0;
static int[] arr = {4,5,26,85,46,19,52,6,37,88,44,8,9,3,22,12,21,23,32,50};
public static void main(String[] args) {
for (int a : arr) {
System.out.print(a+"、");
}
quickSort(0,arr.length-1);
}
private static void quickSort(int left, int right) {
if(left < right){
int pIndex = partition(left,right); //对数组进行划分,并返回划分的下标
System.out.println("\n第"+(++sum)+"轮排序后");
for (int a : arr) {
System.out.print(a+"、");
}
quickSort(left,pIndex);
quickSort(pIndex+1,right);
}
}
private static int partition(int left, int right) {
int baseLine = new Random().nextInt(right-left)+left;
System.out.print("\n随机生成的节点:"+baseLine);
int baseValue = arr[baseLine];
while(true){
while(arr[left] < baseValue){
left++;
}
while(arr[right] > baseValue){
right--;
}
if(left >= right){
break;
}
System.out.print("\n两个数交换,左:"+left+"右:"+right);
swap(left,right);
}
return left;
}
//交换
private static void swap(int left, int right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
}
package algorithm;
/**
* 特点:高效,时间复杂度为nlogn。
* 采用分治法的思想:首先设置一个轴值pivot,然后以这个轴值为划分基准将待排序序列分成比pivot大和比pivot小的两部分,
* 接下来对划分完的子序列进行快排直到子序列为一个元素为止。
* @author change
*
*/
public class FastSort {
public static void main(String[] args) {
int[] array = { 37, 47, 23, 100, 19, 56, 56, 99, 9 };
FastSort fs = new FastSort();
fs.quickSort(array,0,array.length-1);
for (int a : array) {
System.out.print(a+",");
}
}
public void quickSort(int[] array,int low,int high){
int pivot,p_pos,i,t;
if(low<high){
p_pos = low;
pivot = array[p_pos];
for (i = low+1; i <= high; i++) {
if(array[i]<pivot){
p_pos++;
t = array[p_pos];
array[p_pos] = array[i];
array[i] = t;
}
}
t = array[low];
array[low] = array[p_pos];
array[p_pos] = t;
//分而治之 递归
quickSort(array, low, p_pos - 1);// 排序左半部分
quickSort(array, p_pos + 1, high);// 排序右半部分
}
}
}
2、插入排序
package algorithm;
/**
* 特点:效率低,容易实现。
* 思想:将数组分为两部分,将后部分元素逐一与前部分元素比较,如果当前元素array[i]小,就替换。找到合理位置插入array[i]
* @author change
*
*/
public class InsertionSort {
public static void main(String[] args) {
int array[] = {57,68,59,52};
int i,j,temp = 0;
for (i = 0; i < array.length; i++) {
temp = array[i];
for (j = i-1; j >=0 && temp < array[j]; j--) {
array[j+1] = array[j];
}
array[j+1] = temp;
}
for (int k : array) {
System.out.print(k+",");
}
}
}
3、直接插入排序
package algorithm;
/**
* 直接插入排序
* 每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。
* @author change
* 分析
* 直接插入排序是稳定的排序。
* 文件初态不同时,直接插入排序所耗费的时间有很大差异。
* 若文件初态为正序,则每个待插入的记录只需要比较一次就能够找到合适的位置插入,故算法的时间复杂度为O(n),这是最好的情况。
* 若初态为反序,则第i个待插入记录需要比较i+1次才能找到合适位置插入,故时间复杂度为O(n2),这是最坏的情况。
* 直接插入排序的平均时间复杂度为O(n2)。而且还要对数组中的数字进行逐个移位,所以性能比较差。
*/
public class StraightInsertionSort {
static int[] arr = {57,68,59,52,12,10,4,1};
public static void main(String[] args) {
for (int i = 1; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
if(arr[j]>arr[i]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for (int a : arr) {
System.out.print(a+"、");
}
}
}
4、二分法插入排序
package algorithm;
import java.util.Scanner;
/**
* 二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。
* @author change
* 直接插入排序算法,在排序数据量比较大的时候,二分插入排序的速度就要远远高于直接插入排序,那么二分插入排序算法的思想是什么呢?
* 二分插入排序通过从第二个数开始将需要排序的数分为两个部分,左边部分有序,右边部分无序,
* 然后从右边部分第一个数开始,一个一个插入前面有序部分,与直接插入排序唯一不同的是:二分插入排序会先找出左边有序部分的中间值,然后与需要插入的值比较,
* 所以在插入之前,就只需要与左边有序部分的一半值进行比较。因此,在数据量比较大的时候,二分插入排序算法就更加高效,速度更快。
*/
public class BinarySort {
static int[] arr = {57,68,59,52,12,10,4,1};
//二分插入算法
public void binaryInsertSort(int[] str){
for (int i = 1; i < str.length; i++) {
if (str[i]<str[i-1]) {
int temp = str[i]; //定义temp存储所要插入的数
int left = 0; //最左边的数,从str[0]开始
int right = i-1; //最右边位,所要插入那个数的前一位
while(left<=right){
int mid = (left+right)/2; //mid中间位
if (str[mid]<temp) { //中间位与str[i]比较
left = left + 1;
}else { //通过if语句找到应该插入的位置str[left]
right = right - 1;
}
}
for (int j = i; j>left; j--) { //将str[left]->str[i-1]的数都往后移一位
str[j]=str[j-1];
}
str[left]=temp; //最后将str[i]插入str[left]
}
}
}
//主函数
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个数组:");
String s1 = scanner.nextLine();
String[] s2 = s1.split(",");
int[] str = new int[s2.length];
for (int i = 0; i < str.length; i++) {
str[i] = Integer.valueOf(s2[i]);
}
BinarySort bis = new BinarySort();
bis.binaryInsertSort(str);
System.out.println("排序后:");
for (int i = 0; i < str.length; i++) {
System.out.print(str[i]+" ");
}
scanner.close();
}
}
5、冒泡排序
package algorithm;
public class BubbleSort {
static int[] arr = {57,68,59,52};
public static void main(String[] args) {
int temp = 0;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if(arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for (int a : arr) {
System.out.print(a+"、");
}
}
}