快排:将原始数组分成两个子数组,第一个子数组中的元素小于或等于某个选定的关键字,这个关键字就是基准,第二个数组大于这个基准,然后对这两个数组进行单独排序,但在排序之前要对每个数组进行反复的划分操作,直到划分到只含有一个元素的数组,这时就把数组分成了单个的元素。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。
归并排序:归并排序主要是将多个已经排好序的数组组合并成一个排好序的数组,这些子数组必须先排好序,方法是先将数组拆分成一个元素的数组,然后再将他们两两合并在一起,然后依次将合并的数组在合并。
堆排序:利用堆的特性,堆顶是最大值或者最小值,每次取得最大值(最小值)变的特别方便。
1、将初始待排序关键字序列(a1,a2....an)构建成大顶堆,此堆为初始的无须区;
2、将堆顶元素a[1]与最后一个元素a[n]交换,此时得到新的无序区(a1,a2,......an-1)和新的有序区(an),且满足a[1,2...n-1]<=a[n];
3、由于交换后新的堆顶a[1]可能违反堆的性质,因此需要对当前无序区(a1,a2,......an-1)调整为新堆,然后再次将a[1]与无序区最后一个元素交换,得到新的无序区(a1,a2....an-2)和新的有序区(an-1,an)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
public class MySort {
public static void main(String [] args) {
int [] array = {10,4,7,5,9,10,40,50,20,8,12,11,28};
int [] temp = new int [array.length];
//Sort.mergeSort(array, 0, array.length-1, temp);
//Sort.quickSort(array, 0, array.length-1);
//Sort.insertSort(array);
//Sort.selectionSort(array);
//Sort.bubbleSort(array);
Sort.heapSort(array, array.length);
for(int i=0;i<array.length;i++)
System.out.print(array[i]+" ");
}
}
class Sort{
// 快排
public static void quickSort(int [] array, int first, int last) {
if(first<last) {
int temp = partition(array,first,last);
//System.out.println(temp);
quickSort(array,temp,last-1);
quickSort(array,first,temp-1);
}
}
public static int partition(int [] array,int left, int right) {
int priot = array[left];
int first = left;
int last = right;
while(first<last) {
//System.out.println("first="+first+" last="+last);
while(first<last && array[last]>=priot) {
last--;
}
if(first<last) {
array[first] = array[last];
first++;
}
while(first <last && array[first]<=priot){
first++;
}
if(first<last) {
array[last]=array[first];
last--;
}
}
array[first]=priot;
return first;
}
//归并排序
//将有序数列a[first...mid]和a[mid...last]合并
public static void mergeArray(int a[],int first, int mid, int last,int temp[]) {
int i = first,j = mid+1;
int m = mid, n=last;
int k=0;
while(i<=m && j<=n) {
if(a[i]<=a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
while(i<=m)
temp[k++] = a[i++];
while(j<=n)
temp[k++] = a[j++];
for(i=0;i<k;i++)
a[first+i] = temp[i]; // 把排好序的数组赋值回去给a
}
public static void mergeSort(int a[],int first,int last,int temp[]) {
if(first<last) {
int mid = (first+last)/2;
//将数组分裂
mergeSort(a,first,mid,temp);
mergeSort(a,mid+1,last,temp);
//将数组合并
mergeArray(a,first,mid,last,temp);
}
}
public static void insertSort( int [] a) { //插入排序,每次把最小的插入到前面去
int length = a.length;
for(int i=1;i<length;i++) {
int temp = a[i];
int j=0;
for( j=i; j>0 && temp<a[j-1];j--) { //把大于temp的值往后移动一位,然后把temp插入到合适的位置
a[j] = a[j-1];
}
a[j] = temp;
}
}
public static void selectionSort(int [] a) { //选择排序
int length = a.length;
for(int i=0;i<length-1;i++) {
int index = i;
for(int j=i+1;j<length;j++) {
if(a[j]<a[index])
index = j;
}
Sort.swap(a, i, index);
}
}
public static void bubbleSort(int [] a) {
int length = a.length;
for(int i=0;i<length-1;i++) {
for(int j=length-1; j>i; j--) {
if(a[j] < a[j-1])
Sort.swap(a, j, j-1);
}
}
}
public static void swap(int [] a,int i,int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void heapSort(int [] a,int size) {
for(int i=size/2-1;i>=1;i--) {
Sort.moveDown(a, i, size-1); // 首先让他变成最大堆
}
for(int i= size-1;i>=0;i--) {
Sort.swap(a, 0, i); // 把最大的值放到数组最后一位
Sort.moveDown(a, 0, i-1); //把数组中最后一位剔除,再进行调整为最大堆
}
}
public static void moveDown(int [] a,int first,int last) {
int largest = 2*first+1;
while(largest < last) {
if(largest < last && a[largest] < a[largest+1]) //父节点有两个子节点
largest++;
if(a[first] < a[largest]) {
Sort.swap(a, first, largest);
first = largest;
largest = 2*first+1;
}else {
largest = last+1; //退出循环
}
}
}
}