• java开发过程中几种常用算法


    排序算法

    排序算法中包括:简单排序、高级排序

    简单排序

     简单排序常用的有:冒泡排序、选择排序、插入排序

    • 冒泡排序代码如下:
     1 private static void bubbleSrot(int[] arr) {
     2 
     3 for (int i = 0; i < arr.length - 1; i++) {
     4 
     5 for (int j = i + 1; j < arr.length; j++) {
     6 
     7 if (arr[i] > arr[j]) {
     8 
     9 int temp = arr[i];
    10 
    11 arr[i] = arr[j];
    12 
    13 arr[j] = temp;
    14 
    15 }
    16 
    17 }
    18 
    19 }
    20 
    21 }
    

       冒泡排序方法速度是很慢的,运行时间为O(N²)级。选择排序改进了冒泡排序,将必要的交换次数从O(N²)减少到O(N),不幸的是比较次数依然是O(N²)级。然而,选择排序依然为大记录量的排序提出了一个非常重要的改进,因为这些大量的记录需要在内存中移动,这就使交换的时间和比较的时间相比起来,交换的时间更为重要。
    ---------------------

    • 选择排序代码如下:
     1 private static void chooseSort(int[] arr) {
     2 
     3 for (int i = 0; i < arr.length; i++) {
     4 
     5 int least = i;
     6 
     7 for (int j = i + 1; j < arr.length; j++) {
     8 
     9 if (arr[j] < arr[least]) {
    10 
    11 least = j;
    12 
    13 }
    14 
    15 }
    16 
    17 // 将当前第一个元素与它后面序列中的最小的一个 元素交换,也就是将最小的元素放在最前端
    18 
    19 int temp = arr[i];
    20 
    21 arr[i] = arr[least];
    22 
    23 arr[least] = temp;
    24 
    25 }
    26 
    27 }

       选择排序的效率:选择排序和冒泡排序执行了相同次数的比较:N*(N-1)/2。对于10个数据项,需要45次比较,然而,10个数据项只需要少于10次的交换。对于100个数据项,需要4950次比较,但只进行不到100次交换。N值很大时,比较的次数是主要的,所以结论是选择排序和冒泡哦排序一样运行了O(N²)时间。但是,选择排序无疑更快,因为它进行的交换少得多。
    ---------------------

    • 插入排序代码如下
     1 private static void insertionSort(int[] arr) {
     2 
     3 int in, out;
     4 
     5 for (out = 1; out < arr.length; out++) {
     6 
     7 int temp = arr[out];
     8 
     9 in = out;
    10 
    11 while (in > 0 && arr[in - 1] >= temp) {
    12 
    13 arr[in] = arr[in - 1];
    14 
    15 --in;
    16 
    17 }
    18 
    19 arr[in] = temp;
    20 
    21 }
    22 
    23 }

       插入排序的效率:这个算法中,第一趟排序,最多比较一次,第二趟排序,最多比较两次,以此类推,最后一趟最多比较N-1次,因此有1+2+3+…+N-1 = N*(N-1)/2。然而,因为在每一趟排序发现插入点之前,平均只有全体数据项的一半真的进行了比较,所以除以2最后是N*(N-1)/4。
    对于随机顺序的数据,插入排序也需要O(N²)的时间级。当数据基本有序,插入排序几乎只需要O(N)的时间,这对把一个基本有序的文件进行排序是一个简单而有效的方法。
      对于逆序排列的数据,每次比较和移动都会执行,所以插入排序不比冒泡排序快。
    ---------------------

    • 归并排序

     1 // 将两个已排序的数组合并到第三个数组上。
     2 
     3 private static void merge(int[] arrA, int[] arrB, int[] arrC) {
     4 
     5 int aDex = 0, bDex = 0, cDex = 0;
     6 
     7 int sizeA = arrA.length;
     8 
     9 int sizeB = arrB.length;
    10 
    11 
    12 // A数组和B数组都不为空
    13 
    14 while (aDex < sizeA && bDex < sizeB) {
    15 
    16 if (arrA[aDex] < arrB[bDex]) {
    17 
    18 arrC[cDex++] = arrA[aDex++];
    19 
    20 } else {
    21 
    22 arrC[cDex++] = arrB[bDex++];
    23 
    24 }
    25 
    26 }
    27 
    28 // A数组不为空,B数组为空
    29 
    30 while (aDex < sizeA) {
    31 
    32 arrC[cDex++] = arrA[aDex++];
    33 
    34 }
    35 
    36 // A数组为空,B数组不为空
    37 
    38 while (bDex < sizeB) {
    39 
    40 arrC[cDex++] = arrB[bDex++];
    41 
    42 }
    43 
    44 }

    高级排序

      常见的高级排序:哈希排序、快速排序,这两种排序算法都比简单排序算法快得多:希尔排序大约需要O(N*(logN)²)时间,快速排序需要O(N*logN)时间。这两种排序算法都和归并排序不同,不需要大量的辅助存储空间。希尔排序几乎和归并排序一样容易实现,而快速排序是所有通用排序算法中最快的一种排序算法。 还有一种基数排序,是一种不常用但很有趣的排序算法。

    • 哈希排序

      哈希排序是基于插入排序的,实现代码如下:

     1 private static void shellSort(int[] arr) {
     2 
     3 int inner, outer;
     4 
     5 int temp;
     6 
     7 int h = 1;
     8 
     9 int nElem = arr.length;
    10 
    11 while (h <= nElem / 3) {
    12 
    13 h = h * 3 + 1;
    14 
    15 }
    16 
    17 while (h > 0) {
    18 
    19 for (outer = h; outer < nElem; outer++) {
    20 
    21 temp = arr[outer];
    22 
    23 inner = outer;
    24 
    25 while (inner > h - 1 && arr[inner - h] >= temp) {
    26 
    27 arr[inner] = arr[inner - h];
    28 
    29 inner -= h;
    30 
    31 }
    32 
    33 arr[inner] = temp;
    34 
    35 }
    36 
    37 h = (h - 1) / 3;
    38 
    39 }
    40 
    41 }
    42 --------------------- 
    • 快速排序

      快速排序是最流行的排序算法,在大多数情况下,快速排序都是最快的,执行时间是O(N*logN)级,划分是快速排序的根本机制。划分本身也是一个有用的操作。 划分数据就是把数据分为两组,使所有关键字大于特定值的数据项在一组,所有关键字小于特定值的数据项在另一组。代码实现如下:

     1 // 快速排序
     2 
     3 private static void recQuickSort(int arr[], int left, int right) {
     4 
     5 if (right - left <= 0) {
     6 
     7 return;
     8 
     9 } else {
    10 
    11 int pivot = arr[right];// 一般使用数组最右边的元素作为枢纽
    12 
    13 int partition = partitionIt(arr, left, right, pivot);
    14 
    15 recQuickSort(arr, left, partition - 1);
    16 
    17 recQuickSort(arr, partition + 1, right);
    18 
    19 }
    20 
    21 }
    22 
    23 
    24 // 划分
    25 
    26 private static int partitionIt(int[] arr, int left, int right, int pivot) {
    27 
    28 int leftPtr = left - 1;
    29 
    30 // int rightPtr = right + 1;
    31 
    32 int rightPtr = right; // 使用最右边的元素作为枢纽,划分时就要将最右端的数据项排除在外
    33 
    34 while (true) {
    35 
    36 while (arr[++leftPtr] < pivot)
    37 
    38 ;
    39 
    40 while (rightPtr > 0 && arr[--rightPtr] > pivot)
    41 
    42 ;
    43 
    44 
    45 if (leftPtr >= rightPtr) {
    46 
    47 break;
    48 
    49 } else {
    50 
    51 // 交换leftPtr和rightPtr位置的元素
    52 
    53 int temp = arr[leftPtr];
    54 
    55 arr[leftPtr] = arr[rightPtr];
    56 
    57 arr[rightPtr] = temp;
    58 
    59 }
    60 
    61 }
    62 
    63 // 交换leftPtr和right位置的元素
    64 
    65 int temp = arr[leftPtr];
    66 
    67 arr[leftPtr] = arr[right];
    68 
    69 arr[right] = temp;
    70 
    71 return leftPtr;// 返回枢纽位置
    72 
    73 }
    74 --------------------- 

    查找算法

    对于有序的数组,常用的查找算法:二分查找。代码如下:

     1 private static int find(int [] arr,int searchKey){
     2 
     3         int lowerBound = 0;
     4 
     5         int upperBound = arr.length -1;
     6 
     7         int curIn;
     8 
     9         while(lowerBound <= upperBound){
    10 
    11             curIn = (lowerBound + upperBound) / 2;
    12 
    13             if(arr[curIn] == searchKey){
    14 
    15                 return curIn;
    16 
    17             }else{
    18 
    19                 if(arr[curIn] < searchKey){
    20 
    21                     lowerBound = curIn + 1;
    22 
    23                 }else{
    24 
    25                     upperBound = curIn - 1;
    26 
    27                 }
    28 
    29             }
    30 
    31         }
    32 
    33         return -1;
    34 
    35     }
    36 --------------------- 
    不经历风雨,怎能见彩虹?做一个快乐的程序员。
  • 相关阅读:
    纯数学教程 Page 325 例LXVIII (12)
    纯数学教程 Page 325 例LXVIII (11) Math.Trip.1927,1928
    纯数学教程 Page 325 例LXVIII (11) Math.Trip.1927,1928
    纯数学教程 Page 325 例LXVIII (9)
    纯数学教程 Page 325 例LXVIII (14) $\frac{1}{1^2}+\frac{1}{3^2}+\frac{1}{5^2}+\cdots=\frac{3}{4}(\frac{1}{1^2}+\frac{1}{2^2}+\frac{1}{3^2}+\cdots)$
    纯数学教程 Page 325 例LXVIII (14) $\frac{1}{1^2}+\frac{1}{3^2}+\frac{1}{5^2}+\cdots=\frac{3}{4}(\frac{1}{1^2}+\frac{1}{2^2}+\frac{1}{3^2}+\cdots)$
    纯数学教程 Page 325 例LXVIII (13)
    纯数学教程 Page 325 例LXVIII (12)
    纯数学教程 Page 325 例LXVIII (9)
    纯数学教程 Page 325 例LXVIII (13)
  • 原文地址:https://www.cnblogs.com/Mr-Elliot/p/10015459.html
Copyright © 2020-2023  润新知