今天有感,记录于此
一、冒泡排序
public static void bubbleSort(int[] arr){ for(int i=0;i<arr.length-1;i++){ for(int j=0;j<arr.length-i-1;j++){ if(arr[j+1]<arr[j]){ int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } for (int i : arr) { System.out.println(i); } }
冒泡排序法存在的不足及改进方法:
第一,在排序过程中,执行完最后的排序后,虽然数据已全部排序完备,但程序无法判断是否完成排序,为了解决这一不足,可设置一个标志位flag,将其初始值设置为非0,表示被排序的表是一个无序的表,每一次排序开始前设置flag值为0,在进行数据交换时,修改flag为非0。在新一轮排序开始时,检查此标志,若此标志为0,表示上一次没有做过交换数据,则结束排序;否则进行排序;
public static void bubbleSort(int[] arr){ int flag;//标识位 for(int i=0;i<arr.length-1;i++){ flag=0; for(int j=0;j<arr.length-i-1;j++){ if(arr[j+1]<arr[j]){ int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; flag=1;//发生了交换,标识位置为1 } } if(flag==0)//此趟循环没有发生数据交换,证明排序完成,直接跳出循环 break; } for (int i : arr) { System.out.println(i); } }
二、快速排序
public static void quickSort(int arr[],int low,int high){ int i=low; int j=high; int key=arr[low];//选择第一个元素作为枢纽元素 if(low<high){ while(i<j){ while(i<j&&arr[j]>=key){ j--; } if(i<j){ arr[i]=arr[j]; i++; } while(i<j&&arr[i]<=key){ i++; } if(i<j){ arr[j]=arr[i]; j--; } } arr[i]=key; sort(arr,low,i-1); sort(arr,i + 1,high); } }
三、插入排序
public static void insertSort(int[] arr){ for(int i=1;i<arr.length;i++){ for(int j=i;(j>0&&arr[j]<arr[j-1]);j--){//下一个元素插入前面排好的数值 int temp=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temp; } } }
四、选择排序
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
public static void selectSort(int[] arr){ for(int i=0;i<arr.length;i++){ int min=arr[i]; int index=i; for(int j=i;j<arr.length-1;j++){//找出为分组的最小数值 if(arr[j+1]<min){ min=arr[j+1]; index=j+1; } } arr[index]=arr[i]; arr[i]=min; } }
五、shell 排序
public static void shellSort(int[] arr,int index){ for(int i=0;i<index&&i<arr.length;i++){ int count=(arr.length-1-i)/index; int[] temparr=new int[count+1]; for(int j=0;j<=count;j++){ temparr[j]=arr[i+j*index]; } insertSort(temparr); for(int j=0;j<=count;j++){ arr[i+j*index]=temparr[j]; } } index=index-1; if(index>0) shellSort(arr,index); }
在oschina上看见了别人的算法,牛的一逼
public static int[] shellSort(int[] arr){ int i,j,n=1,temp,len = arr.length; while(n<=len/3) n = n*3+1; while(n > 0){ for (i = n; i < len; i++) { temp = (Integer) arr[i]; j = i; while(j >= n && (Integer)arr[j - n] >= temp){ arr[j] = arr[j - n]; j-=n; } arr[j] = temp; } n = (n - 1)/3; } return arr; }那个for里面的写的太精彩了
六、堆排序
1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;
2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
对于堆排序,最重要的两个操作就是构造初始堆和调整堆 :
/** * 建立堆 * * @param args */ public static void bulidHeap(int[] arr, int size) { int i; for (i = (arr.length / 2) - 1; i >= 0; i--) // 非叶节点最大序号值为size/2 { swapHeap(arr, i, size); } } /** * 调整堆 * @param args */ public static void swapHeap(int[] arr, int i, int size) { int lchild = 2 * i + 1; // i的左孩子节点序号 int rchild = 2 * i + 2; // i的右孩子节点序号 int max = i; // 临时变量 if (i <= size / 2) // 如果i是叶节点就不用进行调整 { if (lchild < size && arr[lchild] > arr[max]) { max = lchild; } if (rchild < size && arr[rchild] > arr[max]) { max = rchild; }//取得max为父子结点中,最大的结点index if (max != i) { int temp = arr[max]; arr[max] = arr[i]; arr[i] = temp; swapHeap(arr, max, size); // 避免调整之后以max为父节点的子树不是堆,继续调整为大顶堆 } } }
/** * 堆排序 * * @param args */ public static void heapSort(int[] arr) { bulidHeap(arr, arr.length);// 构建初始堆 for (int i = arr.length - 1; i > 0; i--) {//选择堆中第一个元素与最后一个元素交互,重新调整堆,以此类推 int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; swapHeap(arr, 0, i);//重新调整余下元素,chengw } }
end