package com.example.lib.sort; /** * Created by mengjk on 18-4-28. */ public class Sort { public static void main(String[] args){ int[] array={7,12,1,6,3,10,8,26,5,3,11}; maopao1(array); printResult("-result",array); } //最前便利冒泡 private static void maopao1(int[] array){ System.out.println("mapao1"); //普通方式,从前面遍历,比较交换 for(int i=0;i<array.length;i++){ for (int j=i+1;j<array.length;j++){ if(array[i]>array[j]){ swap(array,i,j); } } } } //从后便利冒泡 private static void maopao2(int[] array){ System.out.println("mapao2"); //从后往前遍历,比较并交换,减少比较次数 for(int i=0;i<array.length;i++){ for (int j=array.length-1;j>=i;j--){ if(array[i]>array[j]){ swap(array,i,j); } } } } //直接选择排序 private static void select1(int[] array){ System.out.println("select1"); for(int i=0;i<array.length;i++){ //每次找出当前项的剩余序列中最小/最大值跟当前项交换。 int min=i; for (int j=i+1;j<array.length;j++){ if(array[min]<array[j]){ min=j;//记下最小/最大值 } } if(min!=i){//如果发现有这样的值,则交换 swap(array,i,min); } } printResult("-result",array); } //直接插入排序 private static void inser(int[] array){ System.out.println("inser2"); for (int i = 1; i < array.length; i++) { int j=0; int temp = array[i]; // 取出第i个数,和前i-1个数比较后,插入合适位置 // 因为前i-1个数都是从小到大的有序序列,所以只要当前比较的数(list[j])比temp大,就把这个数后移一位 for (j = i - 1; j >= 0 && temp < array[j]; j--) { array[j + 1] = array[j]; } array[j + 1] = temp; } printResult("-result",array); } //希尔排序 private static void shell(int[] array) { System.out.println("shell"); /* gap 9/2=4 12-10,1-8,6-26,3-5,10-3 4个间隔为一组,排完是 10,1,6,3,3,12,8,26,5 gap 4/2=2 相隔是2个间隔的数据为一组, 10-6-3-8-5,1-3-12-26,。。。把这些排序一下。 * */ //增量gap,并逐步缩小增量 for (int gap = array.length / 2; gap > 0; gap /= 2) { //从第gap个元素,逐个对其所在组进行直接插入排序操作 for (int i = gap; i < array.length; i++) { int j = i; while (j - gap >= 0 && array[j] < array[j - gap]) { //插入排序采用交换法 swap(array, j, j - gap); j -= gap; //这是一个组,对每一个gap生成的一组数据进行排序,j-=gap能确保是本组中往前一个对比,直到对比完 } } } printResult("-result", array); } //堆排序 private static void heap(int[] array) { System.out.println("shell"); int len = array.length -1; for(int i = len/2 - 1; i >=0; i --){ //堆构造,只有len/2-1之前的节点才有子结点。 heapAdjust(array,i,len); } while (len >=0){ swap(array,0,len--); //将堆顶元素与尾节点交换后,长度减1,尾元素最大 heapAdjust(array,0,len); //再次对堆进行调整 } printResult("-result", array); } public static void heapAdjust(int[] arr,int i,int len){ int left,right,j ; while((left = 2*i+1) <= len){ //判断当前父节点有无左节点(即有无孩子节点,left为左节点) right = left + 1; //右节点 j = left; //j"指针指向左节点" if(j < len && arr[left] < arr[right]) //右节点大于左节点 j ++; //当前把"指针"指向右节点 if(arr[i] < arr[j]) //将父节点与孩子节点交换(如果上面if为真,则arr[j]为右节点,如果为假arr[j]则为左节点) swap(arr,i,j); else //说明比孩子节点都大,直接跳出循环语句 break; i = j; } } //归并排序 public static void guibin(int []arr){ System.out.println("sort"); int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间 sort(arr,0,arr.length-1,temp); printResult("-result", arr); } private static void sort(int[] arr,int left,int right,int []temp){ if(left<right){//不断的把数组拆分,直到只有一个数为止 int mid=(left+right)/2; sort(arr,left,mid,temp); sort(arr,mid+1,right,temp); merge(arr,left,mid,right,temp); } } private static void merge(int[] arr,int left,int mid,int right,int[] temp){ //把拆分的数组有序的合并起来 int index=left; int i=left,j=mid+1;//用于标识左右两个数组,因为要把这两个数组并成一个有序的数组, while (i<=mid&&j<=right){//方式就是从从左右开始,谁最小就把谁捡到Temp中,并把它的index往前加1 if(arr[i]<=arr[j]){ temp[index]=arr[i]; index++; i++; }else{ temp[index]=arr[j]; index++; j++; } } //上面选择完后,如果还有数据,说明肯定是最大或者最小的有序组,直接把剩下的都放到temp中。 //把左边剩下的都拷贝到数组中 while (i<=mid){ temp[index]=arr[i]; index++; i++; } //把右边剩下的都拷贝到数组中 while (j<=right){ temp[index]=arr[j]; index++; j++; } index--;//因为while中多操作了一步,把它还原回来 //把temp复制到arr中 while (index>=0){ arr[index]=temp[index]; index--; } //printResult("",temp); } //快速排序 private static void quik(int[] array){ //对每一次数组,都以第一个下标的数据为中枢,然后把数组中的所有数据,小的都放到中枢左边,大的都放到中枢的右边 //然后再把中枢的左边当成一个新的数组再排序,中枢右边的数组也是一样 System.out.println("quik"); qsort(array,0,array.length-1); printResult("-result",array); } private static void qsort(int[] arr, int low, int high){ if (low < high){ int pivot=partition(arr, low, high); //将数组分为两部分 qsort(arr, low, pivot-1); //递归排序左子数组 qsort(arr, pivot+1, high); //递归排序右子数组 } } //不需要交换的快排 private static int partition(int[] arr, int low, int high){ int pivot = arr[low]; //枢轴记录 while (low<high){ //相当于把这个中枢当成一个空位就对了。 while (low<high && arr[high]>=pivot) --high;//只要遍历到的数比中枢大,说明是不用交换的,继续向下找,这样做能省效率 // 如果找到那么就停止并交换 arr[low]=arr[high]; //交换比枢轴小的记录到左端 while (low<high && arr[low]<=pivot) ++low;//同理, arr[high] = arr[low]; //交换比枢轴小的记录到右端 } //扫描完成,枢轴到位 arr[low] = pivot; //返回的是枢轴的位置 return low; } //使用交换来实现,快排 private static int partition2(int[] arr, int low, int high){ int pivot = low; //枢轴记录 while (low<high){ while (low<high){ if(arr[high]<arr[pivot]){ swap(arr,high,pivot); pivot=high; high--; break; } high--; } while (low<high){ if(arr[low]>arr[pivot]){ swap(arr,low,pivot); pivot=low; low++; break; } low++; } } //返回的是枢轴的位置 return pivot; } private static void swap(int[] array,int i,int j){ int temp=array[i]; array[i]=array[j]; array[j]=temp; } private static void printResult(String index,int[] array){ StringBuilder sb=new StringBuilder(); for(int i=0;i<array.length;i++){ if(i==array.length-1){ sb.append(""+array[i]); }else{ sb.append(""+array[i]+","); } } System.out.println("sort"+index+": "+sb.toString()); } }
排序算法
最新推荐文章于 2022-04-27 23:04:16 发布