/*
1、对给定数组进行排序。
{5,1,6,4,2,8,9}
//Arrays.sort(arr);//java中已经定义好的一种排序方式。开发中,对数组排序。要使用该句代码。
2、对给定的数组进行反转。
{3,1,5,6,2} --->
{2,6,5,1,3}
*/
class ArraySort{
static int num=0;
public static void main(String[] args){
int[] arr1={5,1,6,4,2,7,10,12,3,8,4,9,13,22,56};
int[] arr2={5,1,6,4,2,7,10,12,3,8,4,9,13,22,56};
printArr(arr2);
mergeSort(arr2,0,arr2.length-1);
//quickSort(arr2,0,arr2.length-1);
printArr(arr2);
}
//反转数组
public static void reverseArray(int[] arr){
for(int start=0,end=arr.length-1;start<end;start++,end--)
swap(arr,start,end);
}
/*
选择排序。
思路:遍历除最后一个元素的所有元素,依次拿每个元素与后面的每一个元素进行比较
如果大于后面的元素则进行交换。
*/
public static void selectSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
swap(arr,i,j);
//num++;
}
}
}
}
/*
冒泡排序
思路:
从头到尾拿每一个元素(除最后一个)与后面相邻的元素进行比较,
如果大于后面的元素则进行交换。这样最大值将到最后面,
忽略最后一个元素,重复上面的步骤直到完全排序。
*/
public static void bubbleSort(int[] arr){
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])
swap(arr,j,j+1);
}
//快速排序
/*
思路:1、用2个leftPos,rightPos指针,分别指向给定数组arr的首位置和尾位置。
2、记录该数组的首位置的值为基准值base
3、用右指针rightPos开始搜索向左搜索比基准值小的数,
搜索范围在左指针之的右边。找到第一个比基准值小的数后,
右指针指向该位置并将该位置的值arr[rightPos]赋给左指针所指向位置的值arr[leftPos]
4、用左指针leftPos开始搜索向右搜索比基准值大的数,
搜索范围在右指针之前的左边。找到第一个比基准值大的数后,
右指针指向该位置并将该位置的值arr[leftPos]赋给左指针所指向位置的值arr[rightPos]
5、重复3、4步骤,直到左右2指针指向同一位置,将基准值base赋给该位置的值。
6、此时,大于基准值的数都到了右边,小于基准值的数都到了左边
7、若基准值左边还有数,则将左边的所有数作为一个数组重复1-5这5个步骤。
8、若基准值右边还有数,则将右边的所有数作为一个数组重复1-5这5个步骤。
*/
public static void quickSort(int[] arr, int start, int end) {
int leftPos=start,rightPos=end,base=arr[start];
while(leftPos<rightPos){
while(arr[rightPos]>=base && leftPos<rightPos) rightPos--;
arr[leftPos]=arr[rightPos];
while(arr[leftPos]<=base && leftPos<rightPos) leftPos++;
arr[rightPos]=arr[leftPos];
}
arr[leftPos]=base;
//printArr(arr);
//System.out.println("start:"+start+",end:"+end);
if(leftPos-start>=3 ||(leftPos-start==2 && arr[leftPos-1]==arr[leftPos-2]))
quickSort(arr,start,leftPos-1);
if(end-rightPos>=3 ||(end-rightPos==2 && arr[rightPos+1]==arr[rightPos+2]))
quickSort(arr,rightPos+1,end);
}
//插入排序
/*
具体算法描述如下:
⒈ 从第一个元素开始,该元素可以认为已经被排序
⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描
⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置
⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
⒌ 将新元素插入到下一位置中
⒍ 重复步骤2~5
调用方法为:insertSort(arr,0,1);//起始为0,增量为1
*/
public static void insertSort(int[] arr,int start,int increment) {
if(arr.length<2) return;
int i,j,insert;
for(i=start+increment;i<arr.length;i+=increment){//每次循环拿该元素与前面所有元素进行比较
insert=arr[i];
for(j=i-increment;j>=0 && arr[j]>insert;j-=increment){
arr[j+increment]=arr[j];
}
if(j!=i-increment) arr[j+increment]=insert;
}
}
//希尔排序
/*
1、初始增量为数组长度的一半,每次循环完成增量变为原来的一半
2、划分出编号为0~increment-1的组
3、每组是以编号i开始,间隔为increment的所有元素
下面对每一组进行"插入排序"(详见上一种排序方法)
*/
public static void shellSort(int[] arr) {
if(arr.length<2) return;
for(int increment=arr.length/2;increment>=1;increment/=2)
for(int i=0;i<increment;i++)
insertSort(arr,i,increment);
}
//归并排序
/*
归并操作的工作原理如下:
1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置
3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4、重复步骤3直到某一指针超出序列尾
5、将另一序列剩下的所有元素直接复制到合并序列尾
*/
private static void merge(int[] arr,int start1,int start2,int end){
int[] tmp = new int[end-start1+1];
int i=start1,j=start2,num=0;
while(i<start2 && j<=end){
if(arr[i]<=arr[j])
tmp[num++]=arr[i++];
else
tmp[num++]=arr[j++];
}
while(i<start2)
tmp[num++]=arr[i++];
while(j<=end)
tmp[num++]=arr[j++];
System.arraycopy(tmp,0,arr,start1,tmp.length);
for(int a=0;a<start1*2;a++)
System.out.print(" ");
printArr(tmp);
//arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
}
//归并排序
/*
将一个数组不断的递归分解成以中间值为基准的左右两部分
直到每个部分只剩下一个元素,然后不断的进行归并操作。
*/
public static void mergeSort(int[] arr, int start, int end){
if(start<end){
int mid=(start+end)/2;
mergeSort(arr,start,mid);
mergeSort(arr,mid+1,end);
merge(arr,start,mid+1,end);
}
}
public static void printArr(int[] arr){
System.out.print("[");
for(int i=0;i<arr.length;i++){
if(i!=arr.length-1) System.out.print(arr[i]+",");
else System.out.print(arr[i]+"]");
}
System.out.println();
}
public static void swap2(int[] arr,int i,int j){
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
public static void swap(int[] arr,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
1、对给定数组进行排序。
{5,1,6,4,2,8,9}
//Arrays.sort(arr);//java中已经定义好的一种排序方式。开发中,对数组排序。要使用该句代码。
2、对给定的数组进行反转。
{3,1,5,6,2} --->
{2,6,5,1,3}
*/
class ArraySort{
static int num=0;
public static void main(String[] args){
int[] arr1={5,1,6,4,2,7,10,12,3,8,4,9,13,22,56};
int[] arr2={5,1,6,4,2,7,10,12,3,8,4,9,13,22,56};
printArr(arr2);
mergeSort(arr2,0,arr2.length-1);
//quickSort(arr2,0,arr2.length-1);
printArr(arr2);
}
//反转数组
public static void reverseArray(int[] arr){
for(int start=0,end=arr.length-1;start<end;start++,end--)
swap(arr,start,end);
}
/*
选择排序。
思路:遍历除最后一个元素的所有元素,依次拿每个元素与后面的每一个元素进行比较
如果大于后面的元素则进行交换。
*/
public static void selectSort(int[] arr){
for(int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
swap(arr,i,j);
//num++;
}
}
}
}
/*
冒泡排序
思路:
从头到尾拿每一个元素(除最后一个)与后面相邻的元素进行比较,
如果大于后面的元素则进行交换。这样最大值将到最后面,
忽略最后一个元素,重复上面的步骤直到完全排序。
*/
public static void bubbleSort(int[] arr){
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])
swap(arr,j,j+1);
}
//快速排序
/*
思路:1、用2个leftPos,rightPos指针,分别指向给定数组arr的首位置和尾位置。
2、记录该数组的首位置的值为基准值base
3、用右指针rightPos开始搜索向左搜索比基准值小的数,
搜索范围在左指针之的右边。找到第一个比基准值小的数后,
右指针指向该位置并将该位置的值arr[rightPos]赋给左指针所指向位置的值arr[leftPos]
4、用左指针leftPos开始搜索向右搜索比基准值大的数,
搜索范围在右指针之前的左边。找到第一个比基准值大的数后,
右指针指向该位置并将该位置的值arr[leftPos]赋给左指针所指向位置的值arr[rightPos]
5、重复3、4步骤,直到左右2指针指向同一位置,将基准值base赋给该位置的值。
6、此时,大于基准值的数都到了右边,小于基准值的数都到了左边
7、若基准值左边还有数,则将左边的所有数作为一个数组重复1-5这5个步骤。
8、若基准值右边还有数,则将右边的所有数作为一个数组重复1-5这5个步骤。
*/
public static void quickSort(int[] arr, int start, int end) {
int leftPos=start,rightPos=end,base=arr[start];
while(leftPos<rightPos){
while(arr[rightPos]>=base && leftPos<rightPos) rightPos--;
arr[leftPos]=arr[rightPos];
while(arr[leftPos]<=base && leftPos<rightPos) leftPos++;
arr[rightPos]=arr[leftPos];
}
arr[leftPos]=base;
//printArr(arr);
//System.out.println("start:"+start+",end:"+end);
if(leftPos-start>=3 ||(leftPos-start==2 && arr[leftPos-1]==arr[leftPos-2]))
quickSort(arr,start,leftPos-1);
if(end-rightPos>=3 ||(end-rightPos==2 && arr[rightPos+1]==arr[rightPos+2]))
quickSort(arr,rightPos+1,end);
}
//插入排序
/*
具体算法描述如下:
⒈ 从第一个元素开始,该元素可以认为已经被排序
⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描
⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置
⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
⒌ 将新元素插入到下一位置中
⒍ 重复步骤2~5
调用方法为:insertSort(arr,0,1);//起始为0,增量为1
*/
public static void insertSort(int[] arr,int start,int increment) {
if(arr.length<2) return;
int i,j,insert;
for(i=start+increment;i<arr.length;i+=increment){//每次循环拿该元素与前面所有元素进行比较
insert=arr[i];
for(j=i-increment;j>=0 && arr[j]>insert;j-=increment){
arr[j+increment]=arr[j];
}
if(j!=i-increment) arr[j+increment]=insert;
}
}
//希尔排序
/*
1、初始增量为数组长度的一半,每次循环完成增量变为原来的一半
2、划分出编号为0~increment-1的组
3、每组是以编号i开始,间隔为increment的所有元素
下面对每一组进行"插入排序"(详见上一种排序方法)
*/
public static void shellSort(int[] arr) {
if(arr.length<2) return;
for(int increment=arr.length/2;increment>=1;increment/=2)
for(int i=0;i<increment;i++)
insertSort(arr,i,increment);
}
//归并排序
/*
归并操作的工作原理如下:
1、申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2、设定两个指针,最初位置分别为两个已经排序序列的起始位置
3、比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4、重复步骤3直到某一指针超出序列尾
5、将另一序列剩下的所有元素直接复制到合并序列尾
*/
private static void merge(int[] arr,int start1,int start2,int end){
int[] tmp = new int[end-start1+1];
int i=start1,j=start2,num=0;
while(i<start2 && j<=end){
if(arr[i]<=arr[j])
tmp[num++]=arr[i++];
else
tmp[num++]=arr[j++];
}
while(i<start2)
tmp[num++]=arr[i++];
while(j<=end)
tmp[num++]=arr[j++];
System.arraycopy(tmp,0,arr,start1,tmp.length);
for(int a=0;a<start1*2;a++)
System.out.print(" ");
printArr(tmp);
//arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
}
//归并排序
/*
将一个数组不断的递归分解成以中间值为基准的左右两部分
直到每个部分只剩下一个元素,然后不断的进行归并操作。
*/
public static void mergeSort(int[] arr, int start, int end){
if(start<end){
int mid=(start+end)/2;
mergeSort(arr,start,mid);
mergeSort(arr,mid+1,end);
merge(arr,start,mid+1,end);
}
}
public static void printArr(int[] arr){
System.out.print("[");
for(int i=0;i<arr.length;i++){
if(i!=arr.length-1) System.out.print(arr[i]+",");
else System.out.print(arr[i]+"]");
}
System.out.println();
}
public static void swap2(int[] arr,int i,int j){
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
public static void swap(int[] arr,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
下面是快速排序的优化: