一、排序的基本概念

  • 排序:将一个数据元素集合或序列重新排列成按一个数据元素某个数据项值有序的序列

    • 稳定排序:排序前和排序后相同元素的位置关系与初始序列位置一致(针对重复元素来说,相对位置不变)
    • 不稳定排序:排序前和排序后相同元素的位置关系与初始序列相比发生改变
  • 排序算法分类:

    • 内部排序:将所有数据加载到内部存储器中完成,待排序序列完全存放在内存中的排序

      • 插入排序:直接插入和希尔排序

      • 选择排序:直接选择排序和堆排序

      • 交换排序:冒泡排序和快速排序

      • 归并排序

      • 分配排序:桶排序,基数排序,计数排序

    • 外部排序:借助外部存储空间和内存进行排序,参与排序的数据非常多,数据量非常大,常用多路归并排序算法
  • 衡量排序算法的优劣:
    • 时间复杂度:分析关键字的比较次数和记录的移动次数
    • 空间复杂度: 分析排序算法中需要多少辅助内存
    • 稳定性: 若两个记录A和B的关键字值相等,但排序后A、 B的先后次序保持不变,则称这种排序算法是稳定的 
         
  • 算法的特征  
输入(Input) 有0个或多个输入数据,这些输入必须有清楚的描述和定义
输出(Output) 至少有1个或多个输出结果,不可以没有输出结果
有穷性(有限性,Finiteness) 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤
可以在可接受的时间内完成
确定性(明确性,Definiteness) 算法中的每一步都有确定的含义,不会出现二义性
可行性(有效性,Effectiveness) 算法的每一步都是清楚且可行的,能让用户用纸笔计算而求出答案
  • 排序算法比较

    • 希尔排序最坏时间复杂度为N^s,1<s<2
    • 冒泡、直接选择、直接插入排序需要两个for循环,每次只关注一个元素,平均时间复杂度为O(n²))(一遍找元素O(n),一遍找位置O(n))

    • 快速、归并、希尔、堆基于二分思想,log以2为底,平均时间复杂度为O(nlogn)(一遍找元素O(n),一遍找位置O(logn))

    • 稳定性记忆-“快希选堆不稳定”(快牺牲稳定性)

二、直接插入排序

  原理:把n个待排元素看成一个有序表和一个无序表,开始有序表里只有一个元素,无序表里有n-1个元素,每次从无序表去一个元素有序的插入到有序表的适当位置

  • 步骤:

    • 从第一个元素开始,将其视为已排序元素
    • 取出下一个元素,在已经排好序的序列从后向前扫描
    • 如果已排序的元素大于插入值,将排序元素移到下一位置
    • 重复步骤,直到找到已排序的元素小于或等于插入值
    • 将插入值放在找到的元素后面

package Oder;
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
//按升序
int[] arr={101,34,119,1,-1,89};
InsertSort.sort(arr);
System.out.println(Arrays.toString(arr));
}
private static void sort(int[] arr) {
//分成有序和无序两个数组
//每次比较,将无序查到有序的合适位置
for (int i = 1; i <arr.length ; i++) {
int insertValue= arr[i];
int insertIndex= i-1;
while (insertIndex>=0 && insertValue<arr[insertIndex] ){
arr[insertIndex+1]=arr[insertIndex];
insertIndex--;
}
if (insertIndex+1!=i)
{arr[insertIndex+1]=insertValue;}
} }
}

三、希尔排序

  优先比较距离较远的元素。希尔排序又叫缩小增量排序

  • 希尔排序的时间复杂度在O(nlog2n)~o(n^2)之间,大致为O(n^1.3)
  • 由于希尔排序对每个子序列单独比较并进行元素交换,有可能改变相同元素的原始顺序,因此是不稳定排序
  • 步骤
    • 现将待排序序列分割成若干子序列(相隔某个“增量”的元素),然后进行直接插入排序
    • 待整个子序列基本有序,在进行子序列的直接插入排序
    • 增量的确定用gap=arr.length/2;gap>0;gap/=2

  

    

package Oder;

import java.util.Arrays;

public class Shell {
public static void main(String[] args) {
//按升序
int[] arr={8,9,1,7,2,5,3,4,6,0};
//Shell.changeSort(arr);
Shell.insertSort(arr);
System.out.println(Arrays.toString(arr));
}
private static void insertSort(int[] arr) {
//每次都是二分组
//每一组进行直接插入排序
//分组
for(int gap= arr.length/2;gap>0;gap/=2){
//直接插入排序
//确定无序组,有序表为前面的元素
for (int i=gap;i<arr.length;i++){
int index=i;
int val=arr[i];
while (index-gap>=0&&arr[index-gap]>val){
arr[index]=arr[index-gap];
index-=gap;
}
if (index!=i)
arr[index]=val;
}
}
}
}

四、直接选择排序

  原理: 每次把最小值或者最大值放在指定位置,一开始从0~n-1区间上选择一个最小值与位置0 的元素交换,将其放在位置0上,然后在1~n-1范围上选取最小值放在位置1上。

  • 无论初始状态如何,在第i趟排序中选择当前后续序列中最小的元素,因此比较的总次数为∑(n-i)=n(n-1)/2=O(n^2)
  • 最好情况:序列已经排好序,移动次数为0
  • 最坏情况:序列逆序,每次排序都要执行交换操作
  • 由于直接选择排序中存在不相邻元素交换额可能性,因此是不稳定排序

package Oder;

import java.util.Arrays;

public class DirectSelectSort {
public static void main(String[] args) {
//按升序
int[] arr={3,-1,2,5,-2,10,7};
DirectSelectSort.sort(arr);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr) {
int temp=0;
for(int i=0;i<arr.length-1;i++){
int min=i;
for (int j= i+1;j<arr.length;j++){
if(arr[min]>arr[j]){
min=j;
}
}
System.out.println(i+ " "+ min);
if (min!=i){
temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
}
}
}

五、堆排序

  堆排序是直接选择排序的优化,避免了重复比较,采用了树形选择排序,总的比较次数为O(nlog2n),但需要增加额外的空间存放中间比较结果和排序结果

  • 大顶堆:每个结点的值都大于或等于其左右孩子结点的值

  • 小顶堆:每个结点的值都小于或等于其左右孩子结点的值

  • 步骤:

    • 建立初始堆:从n/2开始,它对应着二叉树的最后一个非叶子节点,将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;

    • 交换顶点元素,重新建堆

      • 将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];

      • 当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)

    • 不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。  

  • 在整个排序过程中,共需要进行n/2+n-1次筛选运算,每次筛选都要进行双亲和孩子或兄弟节点的比较,移动次数不会超过二叉树的深度log2n+1,因此时间复杂度为O(nlog2n),交换过程中可能导致重复元素位置变换,是不稳定排序

    

package Oder;

import java.util.Arrays;

public class HeapSort {
public static void main(String[] args) {
//按升序
int[] arr={3,-1,2,5,-2,10,7};
heapSort(arr); } private static void heapSort(int[] arr) {
/*adjustArray(arr, 1, arr.length);
adjustArray(arr,0,arr.length);*/
for (int i=arr.length/2-1;i>=0;i--){
adjustArray(arr,i,arr.length);
}
for (int j=arr.length-1;j>0;j--){
//先交换
int temp=arr[j];
arr[j]=arr[0];
arr[0]=temp;
adjustArray(arr,0,j);
}
System.out.println(Arrays.toString(arr));
} private static void adjustArray(int[] arr, int i, int length) {
if (arr==null||arr.length==0)return;
int temp=arr[i]; //保存当前顶点值
for(int k= 2*i+1;k<length;k=2*k+1){
//每次都是把最左的节点当根
if (k+1<length && arr[k]<arr[k+1]){ //说明他的左节点小于右节点
k++;
}
if (arr[k]<temp){
break;
}else{
arr[i]=arr[k];
i=k;// 就把当前节点的最大值索引赋给了i
}
}
arr[i]=temp;
}
}

六、冒泡排序

  原理:每次处理相邻逆序对,经过一次遍历后,最大的数或最小的数会被确定

  • 一共进行n-1趟循环,每一趟排序次数会减少,因为有k个数据已经被确定,排序次数只有n-k-1

  • 经K轮扫描交换,最大的K个元素必然就位,问题规模缩减至n-k

  • 经过至多n 趟扫描后,排序必然终止

  • 优化策略: 如果在某次循环中发现没有发生一次交换,说明已经排序好,可以提前结束,每趟循环判断flag

  • 如果排序数组已经是有序的,冒泡排序只需要进行一趟比较即可退出,
  • 如果是逆序,需要进行n-1次扫描,n(n-1)/2次比较,总共花费3(n^2-n)/2
  • 冒泡排序不改变相同元素相对位置,是稳定排序算法

  

package Oder;
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] arr={3,-1,2,5,-2,10,7};
//BubbleSort.sort(arr);
BubbleSort.sortBest(arr);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr) {
//遍历次数
for(int i=0;i<arr.length-1;i++){
//一次遍历,将相邻逆序对全部转换,最小的元素排在最前面
for (int j=0;j<arr.length-1-i;j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
} //优化
private static void sortBest(int[] arr) {
int temp=0;
//遍历次数
for(int i=0;i<arr.length-1;i++){
boolean flag=false;
//一次遍历,将相邻逆序对全部转换,最小的元素排在最前面
for (int j=0;j<arr.length-1-i;j++) {
if (arr[j] > arr[j + 1]) {
flag=true;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println(i);
if (!flag) break;
}
}
}

七、快速排序

  原理:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

  • 步骤

    • 从数列中挑出一个元素,称为 “基准”(pivot);

    • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

    • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

  • 快速排序需要一个栈存放每次调用的指针和参数,最大调用次数与递归树的高度一致,理想情况为O(nlog2(n+1)),最坏情况是O(n^2),是不稳定排序

            

package Oder;

import java.util.Arrays;

public class QuickSort {
public static void main(String[] args) {
int[] arr={8,9,1,2,2,5,3,2,6,0};
QuickSort.sort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr, int left, int right) {
//二分法,取中间值作为分界点,左边的比他都小,右边的都比他大,r指代左边的最右边界,l指代右边的最左边界
int pivot=arr[(left+right)/2];
int l =left;
int r=right;
while (l<r){
while(arr[l]<pivot){
//找到左边第一个大于中值的
l++;
}
while (arr[r]>pivot){
//找到右边第一个中值的
r--;
}
//如果左边坐标比右边大,说明不用排了,已经找过界了
// 否则就交换二者值
if(l<r){
int temp= arr[l];
arr[l]=arr[r];
arr[r]=temp;
}else break;
if (arr[l]==pivot)r-=1;
if (arr[r]==pivot) l+=1;
}
if (l==r){
r-=1;
l+=1;
}
if (left<r)
sort(arr,left,r);
if (right>l)
sort(arr,l,right);
}
}
  • 递归优化
package Oder;

import java.util.Arrays;

public class QuickSort {
public static void main(String[] args) {
int[] arr={ 47,29,71,99,78,19,24,47};
QuickSort.sort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr, int left, int right) {
//- 从数列中挑出一个元素,称为 “基准”(pivot);
if (left<right)
{int pivot=partition(arr,left,right);
sort(arr,left,pivot-1);
sort(arr,pivot+1,right);}
} private static int partition(int[] arr, int left, int right) {
int mid=left;
int index=left+1; //轮换法,不是一个一个移
for(int i=index;i<=right;i++){
if (arr[i]<arr[mid]){
swap(arr,i,index); //index一定只是比mid数组元素大的那个索引位置
index++; //每交换一次,index后移一位
}
}
swap(arr,mid,index-1);//将中间值就位
return index-1;
} private static void swap(int[] arr, int left, int right) {
int temp= arr[left];
arr[left]=arr[right];
arr[right]=temp;
}
}

package Oder;

import java.util.Arrays;

public class QuickSort {
public static void main(String[] args) {
int[] arr={ 47,29,71,99,78,19,24,47}; //Shell.changeSort(arr);
QuickSort.sort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr, int left, int right) {
if (left<right){
int mid= quicksort(arr,left,right);
sort(arr,left,mid-1);
sort(arr,mid+1,right);
}
} private static int quicksort(int[] arr, int left, int right) {
int pivot =arr[left];
int index=left+1;
while(index<=right){
//注意数组溢出的可能性
while (index<=right&&arr[index]<=pivot) index++;//从左找到比基准值大的
while (index<=right&&arr[right]>=pivot) right--;//从右找到第一个比基准值小的
if (index>=right) break;
else swap(arr,index,right);
}
arr[left]=arr[right];
arr[right]=pivot;
return right;
} private static void swap(int[] arr, int left, int right) {
int temp= arr[left];
arr[left]=arr[right];
arr[right]=temp;
}
}

八、归并排序

  • 归并排序是将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

  • 步骤

    • 把长度为n的输入序列分成两个长度为n/2的子序列;

    • 对这两个子序列分别采用归并排序;

    • 将两个排序好的子序列合并成一个最终的排序序列。

  • 归并排序的时间复杂度为O(nlogn),空间复杂度是O(n),是稳定排序

   

package Oder;

import java.util.Arrays;

public class MergeSort {
private static int count=0;
public static void main(String[] args) {
int[] arr={ 47,29,89,6,78,2,-9};
int [] temp= new int[arr.length];
MergeSort.mergesort(arr,0,arr.length-1,temp);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(temp)); } private static void mergesort(int[] arr, int left, int right, int[] temp) {
if (left<right){
int mid= (left+right)/2;
//先分组
//每次分组分为左右两个组
mergesort(arr,left,mid,temp);
mergesort(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 i=left;
int j= mid+1;
int k=0;
while (i<=mid&&j<=right)
{if (arr[i]<arr[j]){
temp[k]=arr[i];
k++;
i++;
}else {
temp[k]=arr[j];
k++;
j++;
}
}
while (i<=mid){
temp[k++]=arr[i++];
}
while (j<=right){
temp[k++]=arr[j++];
}
k=0;
int start= left;
while (start<=right){
arr[start++]=temp[k++];
}
System.out.println(++count); } }

九、计数排序

  • 计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

  • 步骤

    • 找出待排序的数组中最大和最小的元素;

    • 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;

    • 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);

    • 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。

  • 计数排序是一个稳定的排序算法。当输入的元素是 n 个 0到 k 之间的整数时,时间复杂度是O(n+k),空间复杂度也是O(n+k),其排序速度快于任何比较排序算法。

  • 当k不是很大并且序列比较集中时,计数排序是一个很有效的排序算法。

  

package Oder;

import java.util.Arrays;

public class CountSort {
public static void main(String[] args) {
int[] arr={ 47,29,71,99,78,19,24,47};
CountSort.sort(arr);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr) {
//先找最大值和最小值
int max= arr[0];
int min =arr[0];
for (int i=0;i<arr.length;i++){
if (max<arr[i]){
max=arr[i];
}
if (arr[i]<min){
min=arr[i];
}
}
//定义最大值和最小值之间的数组
int size= max-min+1;
int[] nums= new int[size];
//有多少个相同的元素就++
for (int i=0;i<arr.length;i++){
nums[arr[i]-min]++;
}
//System.out.println(Arrays.toString(nums));
//还原数组,遍历并--
int index=0;
for(int i=0;i<size;i++){
while (nums[i]>0){
arr[index++]=i+min;
nums[i]--;
}
} }
}

十、桶排序

  • 桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定

  • 原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)

  • 步骤

    • 设置一个定量的数组当作空桶;

    • 遍历输入数据,并且把数据一个一个放到对应的桶里去;

    • 对每个不是空的桶进行排序;

    • 从不是空的桶里把排好序的数据拼接起来。

  • 桶排序最好情况下使用线性时间O(n),桶排序的时间复杂度,取决与对各个桶之间数据进行排序的时间复杂度,因为其它部分的时间复杂度都为O(n)。

  • 桶划分的越小,各个桶之间的数据越少,排序所用的时间也会越少。但相应的空间消耗就会增大

  

package Oder;

import javax.print.DocFlavor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; public class BucketSort {
public static void main(String[] args) {
int[] arr={ 47,29,71,-99,78,19,24,47};
BucketSort.sort(arr);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr) {
//先找到最大值和最小值
int max= arr[0];
int min =arr[0];
for (int i=0;i<arr.length;i++){
if (max<arr[i]){
max=arr[i];
}
if (arr[i]<min){
min=arr[i];
}
}
//确定桶的数量,桶的数量分的越多,内部桶的排序就越快
int bucketNum= (max-min)/arr.length+1;
//创建桶链表
ArrayList<ArrayList<Integer>> bucket=new ArrayList<>(bucketNum);
for (int i=0;i<bucketNum;i++){
bucket.add(new ArrayList<>());
}
//- 遍历输入数据,并且把数据一个一个放到对应的桶里去;商相等的属于同一层级
for (int i=0;i<arr.length;i++){
bucket.get((arr[i]-min)/arr.length).add(arr[i]);
}
System.out.println(bucket);
//- 对每个不是空的桶进行排序;
for (int i=0;i<bucketNum;i++){
Collections.sort(bucket.get(i));
}
//- 从不是空的桶里把排好序的数据拼接起来。
int index=0;
for (int i=0;i<bucketNum;i++){
for (int j=0;j<bucket.get(i).size();j++){
arr[index++]=bucket.get(i).get(j);
}
} }
}

十一、基数排序

  • 基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。

  • 有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。

  • 步骤

    • 取得数组中的最大数,并取得位数;

    • arr为原始数组,从最低位开始取每个位组成radix数组;

    • 对radix进行计数排序(利用计数排序适用于小范围数的特点);

  • 对负数的处理不适用于基数排序,要对负数进行一个转换

    • 如果有负数,就找到最小值,将数组的每一位都加上一个填充数使得最小值为0,最后填回数组时在将每一位填充数减去

    • 将该数组分成负数数组和非负数数组,分别进行基数排序,然后将负数的数组翻转,最后合并

    

package Oder;

import java.util.Arrays;

public class RadixSort {
public static void main(String[] args) {
int[] arr={ 47,29,-71,99,-78,19,-24,47};
RadixSort.sort(arr);
System.out.println(Arrays.toString(arr));
} private static void sort(int[] arr) {
//最大值和先找最小值
int max = arr[0];
int min = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
//如果最小值为负数,则进行处理,加填充数
int addnum = 0;
if (min < 0) {
addnum = -min;
}
for (int i = 0; i < arr.length; i++) {
arr[i] += addnum;
}
//这里就都变成了正数了,最大值也相应的变成了 max+addnum
max += addnum;
//- 取得数组中的最大数,并取得位数;
int digit = 0;
while (max > 0) {
digit++;
max /= 10;
}
System.out.println(digit);
//- arr为原始数组,从最低位开始取每个位组成radix数组;
//10个桶,每一个桶存放是该位数的数组元素,最坏情况下都在一个桶里,那该桶元素就arr.length个
int[][] bucket = new int[10][arr.length];
int[] bucketcount = new int[10]; for (int i = 0, n = 1; i < digit; i++, n *= 10) {
for (int j = 0; j < arr.length; j++) {
bucket[arr[j] / n % 10][bucketcount[arr[j] / n % 10]] = arr[j];
bucketcount[arr[j] / n % 10]++;
}
//还原
int index = 0;
for (int k = 0; k < arr.length; k++) {
if (bucketcount[k] != 0) {
for (int j = 0; j < bucketcount[k]; j++) {
arr[index++] = bucket[k][j];
}
}
bucketcount[k] = 0;
}
} for (int i = 0; i < arr.length; i++) {
arr[i] -= addnum;
}
}
}

十二、总结

  • 内部排序方法性能比较

    • 从平均时间而言,快速排序最快,但在最坏情况下不如堆排序和归并排序
    • 从算法简单性而言, 直接选择排序、直接插入、冒泡排序算法简单
    • 从稳定性而言,快速排序,希尔排序,直接选择排序,堆排序是不稳定的
  • 排序方法选择
    • 当待排序数目较大时,若要求排序稳定,选择归并排序
    • 当待排序数目较大,分布随机,不要求稳定,选择快速排序
    • 当待排序数目较大,关键字会出现正序、逆序,采用堆排序
    • 当待排序数目较小时,记录已接近有序或随机分布,要求排序稳定,选择直接插入排序
    • 当待排序数目较小,不要求稳定,采用直接选择排序
    • 若文件初始状态基本有序(指正序),则应选用直接插入、 冒泡或随机的快速排序

  

java基础---数组的排序算法(3)的更多相关文章

  1. Java基础-数组常见排序方式

    Java基础-数组常见排序方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数据的排序一般都是生序排序,即元素从小到大排列.常见的有两种排序方式:选择排序和冒泡排序.选择排序的特 ...

  2. java基础---数组的查找算法(2)

    一.查找的基本概念 查找分为有序查找和无序查找,这里均以数组为对象,有序查找指的是数组元素有序排列,无序查找指的是数组元素有序或无序排列 平均查找长度(Average Search Length,AS ...

  3. Java数组的排序算法

    在Java中,实现数组的排序算法有很多,如冒泡排序法.选择排序法.直接插入法和快速排序法等.下面介绍几种排序算法的具体 实现. 本文引用文献:Java必须知道的300个问题. 1.冒泡排序法 1.1 ...

  4. Java 的八种排序算法

    Java 的八种排序算法 这个世界,需要遗忘的太多. 背景:工作三年,算法一问三不知. 一.八种排序算法 直接插入排序.希尔排序.简单选择排序.堆排序.冒泡排序.快速排序.归并排序和基数排序. 二.算 ...

  5. Java基础——数组应用之StringBuilder类和StringBuffer类

    接上文:Java基础——数组应用之字符串String类 一.StringBuffer类 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和 ...

  6. java基础-数组的折半查找原理

    java基础-数组的折半查找原理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如果让你写一个数组的查找功能,需求如下:在一个数组中,找一个元素,是否存在于数组中, 如果存在就返回 ...

  7. Shell数组以及排序算法(冒泡、直接选择、反转)

    Shell数组以及排序算法(冒泡.直接选择.反转) 目录 Shell数组以及排序算法(冒泡.直接选择.反转) 一.数组概述 1. 数组的定义 2. 下标的定义 3. 数组的特点 4. 数组定义的方法 ...

  8. 《Java基础——数组的定义与使用》

    Java基础--数组的定义与使用       一. 一维数组: 格式一: 数组类型 数组变量[]=new 数据类型[长度]; //需要后续赋值,且后续赋值时只能为单个元素赋值. 或 数组类型 数组变量 ...

  9. java se系列(四) 函数、数组、排序算法、二分法、二维数组

    1 函数 1.1  数的概述 发现不断进行加法运算,为了提高代码的复用性,就把该功能独立封装成一段独立的小程序,当下次需要执行加法运算的时候,就可以直接调用这个段小程序即可,那么这种封装形形式的具体表 ...

随机推荐

  1. 西门子S7系列以太网通讯处理器功能介绍

    北京华科远创科技有限研发的远创智控型号ETH-YC模块适用于西门子S7-200/S7-300/S7-400.SMART S7-200.西门子数控840D.840DSL.合信.亿维PLC的PPI/MPI ...

  2. Go语言的函数02---参数

    package main import "fmt" /* 常量,变量,函数---源代码的成员 给成员命名的字符称之为[标识符] 合法的标识符有:大小写字母,数字,下划线 命名时不能 ...

  3. CVPR2019论文观察:感知边缘检测的双向级联网络

    CVPR2019论文观察:感知边缘检测的双向级联网络 BDCN:Bi-Directional Cascade Network for Perceptual Edge Detection 摘要 探索多尺 ...

  4. 通过Mellanox ConnectX NIC使用XDP加速

    通过Mellanox ConnectX NIC使用XDP加速 Accelerating with XDP over Mellanox ConnectX NICs XDP(eXpress Data Pa ...

  5. sql 数据库使用注意事项

    1.在对数据库表进行操作时,一定要注意当前操作的是哪一个数据库,否则很容易引起不必要的错误.对于master数据库中的数据文件,尽量不要去对其操作. 2.可通过图形方式对数据库进行备份操作,可通过数据 ...

  6. 用java实现一个ATM机系统(2.0版)

    用java实现一个ATM机系统(2.0版) java实现银行ATM自助取款机,实现功能:用户登录.余额查询.存钱.取钱.转账.修改密码.退出系统. 文章目录 用java实现一个ATM机系统(2.0版) ...

  7. Java IO学习笔记三:MMAP与RandomAccessFile

    作者:Grey 原文地址:Java IO学习笔记三:MMAP与RandomAccessFile 关于RandomAccessFile 相较于前面提到的BufferedReader/Writer和Fil ...

  8. Java抽象类、继承及多态和适配器的实现

    Java继承 方法重写是Java语言多态的特性,必须满足以下条件 在子类中,方法名称与父类方法名称完全相同 方法的参数个数和类型完全相同,返回类型完全相同 方法的访问修饰符访问级别不低于父类同名方法的 ...

  9. pytest skip的使用

    skip跳过用例(无条件跳过,不运行用例) 使用方法: 1.使用跳过装饰器 class TestClass(): @pytest.mark.skip(reason='no way of current ...

  10. MySQL8性能优化

    MySQL8.0 引擎: 来看看MySQL8提供的引擎: 常用引擎: InnoDB:支持事务,行级锁,外键,崩溃修复,多版本并发控制:读写效率相对较差,内存使用相对较高,占用数据空间相对较大. MyI ...