(一)冒泡排序:
前面是已排区间[0,bound]; 后面是待排区间[bound+1,arr.length-1]
private void bobuble(int[]arr){
for(int bound=0;bound<arr.length;bound++){
//控制趟数
for(int j=arr.length-1;j<bound;j--){
//每一趟,比较多少次
if(arr[j-1]>arr[j]){//前面的大于后面的就交换(顺序)
swap(arr,j,j-1);
}
}
}
}
private void swap(int[]arr,int x,int y){
int tmp=arr[x];
arr[x]=arr[y];
arr[y]=tmp;
}
(二·)快速排序
思路:1,先找出基准值(一般取最右面的),从左往右找比基准值大的,从右往左找比基准值小的,交换这两个数,如果相遇的话就跳出循环,交换基准值和相遇的数;
2,在[0,find-1] 和[find+1,arr.length-1]进行递归,终止条件是(left>=right)
public static void quickSort(int []arr){
fastSort(arr,0,arr.length-1);
}
private static void fastSort(int[]arr,int left,int right){
if(left>=right){
return;
}
int ret =find_mid(arr,left,right);
fastSort(arr,0,ret-1);
fastSort(arr,ret+1,right);
}
private static int find_mid(int[]arr,int left,int right){
int baseIndex=right;
int baseValue=arr[baseIndex];
while(left<right){
while (left<right&&arr[left]<=baseValue){
left++;
}
while(left<right&&arr[right]>=baseValue){
right--;
}
swap(arr,left,right);
}
swap(arr,left,baseIndex);
return left;
}
private static void swap(int[]arr,int x,int y){
int tmp=arr[x];
arr[x]=arr[y];
arr[y]=tmp;
}
注意:
(三)归并排序
思路:1,找中间元素的下标(mid=(right+left)/2),2,递归[0,mid) , [mid,right)3,合并这两部分
合并:1,创建一个新的数组来保存合并的结果 2,如果左边的小于或等于右边的值,把左边的值放进新数组中,反之把右边的值放入新数组中,3,如果左边还没有结束,右边结束的话,就把左边剩余的放入新数组中,右边也一样 4,把新数组中的值拷贝到原数组中(万一指排一部分呢)
public void mergerSort(int[]arr){
mergerSortHelp(arr,0,arr.length);
}
private void mergerSortHelp(int[]arr,int left,int right){
if( left>=right || right-left==1){
return;
}
int mid=(left+right)/2;
mergerSortHelp(arr,0,mid);
mergerSortHelp(arr,mid,right);
merger(arr,left,mid,right);
}
private void merger(int[]arr,int left,int mid,int right){
int length=right-left;
int[]newArr=new int[length];
int index=0;
int i=left;
int j=mid;
while (i<mid&&j<right){
if(arr[i]<=arr[j]){
newArr[index++]=arr[i++];
}else {
newArr[index++]=arr[j++];
}
}
while (i<mid){
newArr[index++]=arr[i++];
}
while (j<mid){
newArr[index++]=arr[j++];
}
for(int k=0;k<length;k++){
arr[left+k]=newArr[k];
}
}
(四)堆 排序
思路:1,建堆 2,循环取出堆顶元素放在,最后面 swap(arr,0,arr.length-i-1)
步骤1和步骤2都需要下沉函数shiftDown(arr,arr.length-i-1,0)
第二个参数是数组中有效元素的个数,第三个元素是从哪个位置开始,
待排序区间[0,arr.length-i) 已排序区间[arr.length-i,arr.length)
public void heapSort(int[]arr){
creatHeap(arr);
for(int i=0;i<arr.length;i++){
swap(arr,0,arr.length-i-1);
shiftDown(arr,arr.length-i-1,0);
}
}
private void creatHeap(int[]arr){
for(int i=(arr.length-1-1)/2;i>=0;i--){
shiftDown(arr,arr.length,i);
}
}
private void shiftDown(int[]arr,int size,int index){
int parent=index;
int child=index*2+1;
while(child<size){
if(child+1<size&&arr[child+1]>arr[child]){
child=child+1;
}
if(arr[child]>arr[parent]){
swap(arr,child,parent);
}else {
break;
}
parent=child;
child=child*2+1;
}
}
(五)插入排序
思路:[0,bound) 是已排序空间 [bound,size)待排序空间
把bound元素插入[0,bound)(这个区间是有序的)
public void insert(int[]arr){
for(int bound=1;bound<arr.length;bound++){
int tmp=arr[bound];
int cur=bound-1;
for (;cur>=0;cur--){
if(arr[cur]>tmp){
arr[cur+1]=arr[cur];
}else {
break;
}
}
arr[cur+1]=tmp;
}
}
(六)selectSort排序
思路:[0,bound) 是已排序空间 [bound,size)待排序空间
把待排序区间中的最小值放到已排序空间中(采用打擂台的方式)
public void selectSort(int[]arr){
for(int bound=0;bound<arr.length;bound++){
for(int cur=bound+1;cur<arr.length-1;cur++){
if(arr[bound]>arr[cur]){
swap(arr,bound,cur);
}
}
}
}
(七)希尔排序
public void shellSort(int[]arr){
int gap=arr.length;
while(gap>1){
insertSortGap(arr,gap);
gap/=2;
}
insertSortGap(arr,1);
}
private void insertSortGap(int[]arr,int gap){
for(int bound=1;bound<arr.length;bound++){
int tmp=arr[bound];
int cur=bound-gap;
for(;cur>=0;cur-=gap){
if(arr[cur]>bound){
arr[cur+gap]=arr[cur];
}else {
break;
}
}
arr[cur+gap]=tmp;
}
}