public class Sort {
public static void main(String[] args) {
int[] data={3,6,8,3,2,45,7,567,5,12,234,3465,75,543,2,25,3,4,57,8,78,33,7,43,86,444};
int[] outData = quickSort(data,0,data.length-1);
showData(outData);
}
//冒泡排序
public static int[] bubbleSort(int[] data){
int temp;
for (int i=0;i<data.length;i++){
for (int j=data.length-1;j>i;j--){ //注意j--
if (data[j]<data[j-1]){ //data[j]<data[j-1]的比较
temp=data[j-1];
data[j-1]=data[j];
data[j]=temp;
}
}
}
return data;
}
//选择排序
public static int[] selectSort(int[] data){
int min,temp;
for (int i=0;i<data.length;i++){
min=i; //min的初始化
for (int j=i+1;j<data.length;j++){
if (data[j]<data[min]){
min=j;
}
}
if (min!=i){
temp=data[i];
data[i]=data[min];
data[min]=temp;
}
}
return data;
}
//插入排序
public static int[] insertSort(int[] data){
int temp,j;
for (int i=0;i<data.length-1;i++){
if (data[i]>data[i+1]){
temp=data[i+1];
for (j=i;j>=0 && data[j]>temp ;j--){ //j--的原因在于从后往前挪移数据
data[j+1]=data[j];
}
data[j+1]=temp; //注意上一个for循环最后j--,所以j+1
}
}
return data;
}
//希尔排序
public static int[] shellSort(int[] data){
int temp;
int jump=data.length/2; //jump作为一个阶段
while (jump!=0){
for (int i=jump;i<data.length;i++){ //i从jump开始循环
if (data[i]<data[i-jump]){ //插入排序的变形
temp=data[i];
int j;
for (j=i-jump;j>=0 && data[j]>temp;j-=jump){
data[j+jump]=data[j];
}
data[j+jump]=temp;
}
}
jump=jump/2;
}
return data;
}
//堆排序1
public static int[] headSort(int[] data){
//此循环的目的是将非叶节点排序成完整的大顶堆(data.length/2正好为非叶节点的数量)
for (int i = data.length / 2;i > 0; i--){ //循环从data.length/2到1
headAdjust(data,i,data.length); //i和data.length为二叉树编号(不为0)
}
//此循环的目的是将data[0]与data[i]交换保证data[i]是最大的
for (int i = data.length - 1; i > 0; i--){
int tmp = data[i]; //将data[0]与data[i]交换,把最大的移动到数组最后一个位置
data[i] = data[0];
data[0] = tmp;
headAdjust(data,1,i); //1和i为二叉树编号(不为0)
}
return data;
}
//堆排序2
public static void headAdjust(int[] data,int start,int end){
int tmp = data[start - 1]; //实际的数组下标为:二叉树编号 - 1
for (int j = start * 2; j <= end;j *= 2){ //j也为二叉树编号
if (j < end && data[j-1] < data[j]){ //此步骤为寻找子节点的最大值的编号(在涉及数组时,编号一定要-1)
j++;
}
if (data[j-1] < tmp){ //比较子节点最大值和父节点的大小,如果父节点大,则不交换
break;
}
data[start - 1] = data[j - 1];
start = j;
data[j - 1] = tmp;
}
}
//归并排序1
public static int[] mergeSort(int[] data,int low,int high){ //low与high都为数组下标
int[] resData;
if (low < high){
int mid = (low+high)/2;
mergeSort(data,low,mid); //使逐渐其分为1个数/组
mergeSort(data,mid+1,high);
merge(data,low,mid,high); //合并零散的分组
}
return data;
}
//归并排序2
private static void merge(int[] data, int low, int mid, int high) {
int[] resData = new int[high-low+1]; //保存数据的中间值,注意high-low+1
int i = low;
int j = mid + 1;
int k = 0;
while (i <= mid && j <= high){
if (data[i] < data[j]){ //把较小的数先移到新数组中
resData[k++] = data[i++];
} else {
resData[k++] = data[j++];
}
}
while (i <= mid){ // 把左边剩余的数移入数组
resData[k++] = data[i++];
}
while (j <= high){ // 把右边剩余的数移入数组
resData[k++] = data[j++];
}
for (int o = 0;o < resData.length; o++){ //把新数组中的数覆盖data数组
data[o+low] = resData[o];
}
}
//快速排序1
public static int[] quickSort(int[] data,int low,int high){
if (low<high){
int partition = quickSortPartition(data,low,high); //获取枢纽值
quickSort(data,low,partition-1); //递归至low>=high
quickSort(data,partition+1,high);
}
return data;
}
//快速排序2
public static int quickSortPartition(int[] data,int low,int high){
int pivot=data[low]; //将data[low]作为默认的枢纽记录
while (low<high){
while (low<high && data[high]>=pivot) //注意此节点是while循环,
high--; //在data[high]>=pivot时是正确的排序,所以移动high的值
swap(data, low, high);
while (low<high && data[low]<=pivot)
low++;
swap(data, low, high);
}
return low;
}
//交换num1和num2的数据
public static void swap(int[] data,int num1,int num2){
int temp=data[num1];
data[num1]=data[num2];
data[num2]=temp;
}
//打印数据
public static void showData(int[] data){
System.out.print("[ ");
for(int i:data){
System.out.print(i);
System.out.print(" ");
}
System.out.print("]");
}
}