首先在待排序的序列中找到最小元素,存放在待排序序列的起始位置;然后,从剩下的待排序序列中继续寻找最小元素,放在已排序序列的末尾。以此类推,直到所有的元素排序完毕。
void SelectSort(int a[], int len) { for(int i=0; i<len-1;i++)//i代表了已排序序列中的元素个数 { for(int j=i+1; j<len;j++)//寻找待排序序列中最小元素的过程 { if(a[i]>a[j]) a[i]<————>a[j]; } } }冒泡的含义——越大的元素会经由交换慢慢浮到数列末端。 重复地走访要排序的序列,一次比较相邻的两个元素,若大小与顺序不符就交换,每轮走访后都可以将当前前排最大的数提取出来。
void BubbleSort(int a[], int len) { for(int i=0;i<len;i++) { for(int j=0;j<len-1-i;j++) { if(a[j]>a[j+1]) a[j]<————>a[j+1];//把较大的值往后推,第一轮结束后最后一个值是最大的。 } } }从数组的第2个值开始往前遍历,如果比前置位的值小,则自己必然要插入到前面已排序序列中的某一个位置?哪个位置?由于数组不能直接增减元素个数,故必须通过邻近比较、数组值挪位,来最终确定自己的插入位置。——每次遍历,遍历位置以前序列都是排好的。
void insertSort(int a[],int len) { for(int i=1; i<len; i++) { if(a[i]<a[i-1]) { int j; int temp = a[i];//由于数组通过覆盖来更新,故先记录下当前需要插入到前排的值 for(j=i-1; j>=0 && a[j]>temp; j--) { a[j+1]=a[j];//寻找待插入的位置,如果不是,前面的值就依次挪位;如果是,则跳出循环 } a[j+1]=temp; } } }定义两个指针分别指向待排序序列的首尾,确定一个基准值(一般为待排序序列的第一个值),每一轮比较过后,基准值前面的数都比其小,后方的数都比其大。于是原序列被拆分成了两个小的待排序序列,以此递归,最终实现排序。
找到一个比较好理解的博文:https://blog.csdn.net/nrsc272420199/article/details/82587933 具体的过程如下:
public static void quickSort(int[] A, int low, int high) { if(low<high) { int index = getIndex(A,low,high); quickSort(A,low,index-1);//递归查找 quickSort(A,index+1,high); } } public static int getIndex(int[] A, int l, int h) { int base = A[l]; while(l<h) { while(l < h && A[h]>=base)//h指向的值往前挪,直到找到比基准数小的值。 { h--; } A[l]=A[h];//比基准数小的值赋给l所指向的数组位置 while(l < h && A[l]<=base)//l指向的值往后挪,直到找到比基准数大的值。 { l++; } A[h]=A[l];//比基准数大的值赋给h所指向的数组位置 } A[h] = base; return h; }也称缩小增量排序,是插入排序的改进,将数组分为若干个小数组进行插入排序,逐渐合并成原数组。
public static void shellSort(int[] A, int delta) { int increasement = A.length; do { increasement = (increasement+1)/delta;//初始每个小序列的元素个数为delta,序列总数为increasement个 for(int i=0; i<increasement; i++)//遍历每个小序列,一共increasement个 { //下面是插入排序的操作,注意:每个小序列的第2个元素开始,往前遍历,增量不是1,是increasement for(int j=i+increasement; j<A.length ; j+=increasement) { if(A[j]<A[j-increasement]) { int k; int temp=A[j]; for(k=j-increasement; k>=0 && A[k]>temp ;k-=increasement) { //循环移动覆盖数组值 A[k+increasement]=A[k]; } A[k+increasement]=temp; } } } } while (increasement>1); }利用二叉树的性质。 a.对数组进行二叉树排列,循环遍历每个非叶子节点,若发现子节点的数比自己大,则记录较大值位置max,然后交换两个数的位置,并对发生交换的子节点进行递归,以调整后续的节点相对位置。 b.每一轮遍历,都会把当前的最大值调整到栈顶,因此把栈顶元素与待排序序列的最后一个位置元素相交换。再把需要比较的节点总数减1,继续下一轮遍历。 c.遍历所有轮数结束后,即排序结束。
public static void heapAdjust(int[] Arr, int i ,int size) //size是要比较的节点总数 { int max = i; int left = 2*i+1; int right = 2*i+2; if(left<size && Arr[left]>Arr[max]) max = left; if(right<size && Arr[right]>Arr[max]) max = right; if(max != i) { int temp; temp = Arr[max]; Arr[max] = Arr[i]; Arr[i] =temp; heapAdjust(Arr,max,size); } } public static void heapSort(int[] Arr, int size) { for(int i=(size-1)/2; i>=0; i--)//循环完成一次,堆排序排完一次,都把最大值放在根节点位置上了 { heapAdjust(Arr,i,size); } //把根节点上的那个最大值放到堆顶,对除堆顶外的剩余元素继续进行堆排序,要比较的节点总数是递减的size是要递减的 if(size>0) { int temp; temp = Arr[0]; Arr[0] = Arr[size-1]; Arr[size-1] = temp; heapSort(Arr,--size); } }递归——对整个待排序序列不断递归分解成两份,直至每份小序列只有1个数; 和并——从最小的序列开始,不断排序合并,每次合并后的这部分序列都是有序的。
public static void mergeSort(int[] Arr, int left, int right ) { if(left<right) { int mid = left+(right-left)/2; //防止溢出 mergeSort(Arr,left,mid); //当l和r相差1时,此操作使得两者会相等,只剩一个数,无需再递归,开始合并。否则陷入死循环…… mergeSort(Arr,mid+1,right); merge(Arr,left,mid,right); } } public static void merge(int[] Arr,int left, int mid, int right) //合并操作,针对两个有序序列(把一个序列看成两部分)(l,m)(m+1,r) { int i = left; int j = mid+1; int k = 0; int[] temp = new int[right-left+1]; while(i<=mid && j<=right) //循环比较两个序列中的较小值,此循环直接完成min(m,n)个元素的合并 { if(Arr[i]<Arr[j]) temp[k++] = Arr[i++]; else temp[k++] = Arr[j++]; } while(j<=right) //m<n { temp[k++] = Arr[j++]; } while(i<=mid) //m>n { temp[k++] = Arr[i++]; } //把temp的值重新赋给Arr数组 for(int p=0; p<temp.length; p++) { Arr[p+left] = temp[p]; } }