publicstaticvoidinsertionSort(int[] arr){for(int i =1; i < arr.length; i++){
int tmp = arr[i];
int newIndex = i;for(int j = i -1; j >=0; j--){if(tmp < arr[j]){
arr[j +1]= arr[j];
newIndex = j;}}if(newIndex != i){
arr[newIndex]= tmp;}}}
希尔排序
算法步骤
选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;
按增量序列个数 k,对序列进行 k 趟排序;
每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
代码实现
publicstaticvoidshellSort(int[] arr){for(int step = arr.length /2; step >=1; step /=2){for(int i = step; i < arr.length; i++){
int tmp = arr[i];
int newIndex = i;for(int j = i - step; j >=0; j -= step){if(tmp < arr[j]){
arr[j + step]= arr[j];
newIndex = j;}}if(newIndex != i){
arr[newIndex]= tmp;}}}}
归并排序
算法步骤
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
设定两个指针,最初位置分别为两个已经排序序列的起始位置;
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
重复步骤 3 直到某一指针达到序列尾;
将另一序列剩下的所有元素直接复制到合并序列尾。
代码实现
publicstaticvoidmergeSort(int[] arr){mergeSort(arr,0, arr.length -1);}privatestaticvoidmergeSort(int[] arr, int i, int j){if(i >= j){return;}
int mid =(j + i)/2;mergeSort(arr, i, mid);mergeSort(arr, mid +1, j);merge(arr, i, mid, j);}privatestaticvoidmerge(int[] arr, int i, int mid, int j){
int[] res =newint[j - i +1];
int cur =0;
int p = i;
int q = mid +1;while(p <= mid && q <= j){if(arr[p]> arr[q]){
res[cur++]= arr[q++];}elseif(arr[p]< arr[q]){
res[cur++]= arr[p++];}else{
res[cur++]= arr[q++];
res[cur++]= arr[p++];}}while(p <= mid){
res[cur++]= arr[p++];}while(q <= j){
res[cur++]= arr[q++];}
cur =0;for(int k = i; k <= j; k++){
arr[k]= res[cur++];}}
publicstaticvoidquickSort(int[] arr){quickSort(arr,0, arr.length -1);}privatestaticvoidquickSort(int[] arr, int i, int j){if(i >= j){return;}
int pivot = arr[i];
int p = i;
int q = j;while(p <= q){while(q >=0&& arr[q]> pivot && p <= q){
q--;}while(p < arr.length && arr[p]<= pivot && p <= q){
p++;}if(p <= q){
int tmp = arr[p];
arr[p]= arr[q];
arr[q]= tmp;}}
int tmp = arr[q];
arr[q]= pivot;
arr[i]= tmp;quickSort(arr, i, q -1);quickSort(arr, q +1, j);}
堆排序
算法步骤
创建一个堆 H[0……n-1];
把堆首(最大值)和堆尾互换;
把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
重复步骤 2,直到堆的尺寸为 1。
代码实现
privatestaticvoidheapSort(int[] arr){for(int i =0; i < arr.length; i++){adjustHeap(arr, arr.length - i);swap(arr,0, arr.length - i -1);}}/**
* 调整数组前n位成堆
* @param arr 数组
* @param toIndex 前n位的截止下标
*/privatestaticvoidadjustHeap(int[] arr, int toIndex){for(int i =0; i < toIndex; i++){shiftUp(arr, i);}}/**
* 对于大顶堆,如果指定节点的数值比父节点大的话,就交换位置,即上升,一直递归上升到合适的位置时结束
* @param arr 数组
* @param index 指定节点的下标
*/privatestaticvoidshiftUp(int[] arr, int index){if(index >0&& index < arr.length){
int parentIndex =(index -1)/2;if(arr[parentIndex]< arr[index]){swap(arr, parentIndex, index);}shiftUp(arr, parentIndex);}}/**
* 交换数组的两个指定位置的值
* @param arr 数组
* @param i1 指定位置下标1
* @param i2 指定位置下标2
*/privatestaticvoidswap(int[] arr, int i1, int i2){
int tmp = arr[i1];
arr[i1]= arr[i2];
arr[i2]= tmp;}
计数排序
算法步骤
找出待排序的数组中最大和最小的元素
统计数组中每个值为i的元素出现的次数,存入数组C的第i项
对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
代码实现
publicstaticvoidcountingSort(int[] arr){
int max =0;for(int i =0; i < arr.length; i++){if(arr[i]> max){
max = arr[i];}}
int[] count =newint[max +1];for(int value : arr){
count[value]+=1;}
System.out.println(Arrays.toString(count));
int cur =0;for(int i =0; i < count.length; i++){
int num = count[i];for(int j =0; j < num; j++){
arr[cur++]= i;}}}
publicstaticvoidbucketSort(int[] arr){// 计算最大值与最小值
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;for(int item : arr){
max = Math.max(max, item);
min = Math.min(min, item);}// 计算桶的数量
int bucketNum =(max - min)/ arr.length +1;
ArrayList<ArrayList<Integer>> bucketArr =newArrayList<>(bucketNum);for(int i =0; i < bucketNum; i++){
bucketArr.add(newArrayList<>());}// 将每个元素放入桶for(int value : arr){
int num =(value - min)/(arr.length);
bucketArr.get(num).add(value);}// 对每个桶进行排序for(ArrayList<Integer> integers : bucketArr){
Collections.sort(integers);}// 将桶中的元素赋值到原序列
int index =0;for(ArrayList<Integer> integers : bucketArr){for(Integer integer : integers){
arr[index++]= integer;}}}
基数排序
算法步骤
确定数组中的最大元素有几位(MAX)(确定执行的轮数)
创建0 ~ 9个桶(桶的底层是队列),因为所有的数字元素都是由0 ~ 9的十个数字组成
依次判断每个元素的个位,十位至MAX位,存入对应的桶中,出队,存入原数组;直至MAX轮结束输出数组
代码实现
publicstaticvoidradixSort(int[] arr){
int[][] bucket =newint[10][arr.length];//排序桶用于保存每次排序后的结果,这一位上排序结果相同的数字放在同一个桶里
int[] counts =newint[10];//用于保存每个桶里有多少个数字
int max = Integer.MIN_VALUE;for(int value : arr){
max = Math.max(max, value);}
int n =1;//代表位数对应的数:1,10,100...while(n < max){for(int num : arr){
int digit =(num / n)%10;
bucket[digit][counts[digit]]= num;
counts[digit]++;}
int curIndex =0;for(int j =0; j <10; j++){for(int k =0; k < counts[j]; k++){
arr[curIndex++]= bucket[j][k];}
counts[j]=0;//计数器置为0,用于下一次位排序}
n *=10;}}