Java 数据结构篇-深入了解排序算法(动态图 + 实现七种基本排序算法)

 🔥博客主页: 【小扳_-CSDN博客】
❤感谢大家点赞👍收藏⭐评论✍
  

文章目录

        1.0 实现冒泡排序

        2.0 实现选择排序

        2.1 选择排序的改良升级

        3.0 实现堆排序

        4.0 实现插入排序

        5.0 实现希尔排序

        6.0 实现归并排序

        6.1 递归实现归并排序

        6.2 使用非递归实现归并排序

        6.3 递归归并排序 + 插入排序

        7.0 快速排序

        7.1 单边循环快排

        7.2 双边循环快排

        7.3 快速排序的改良升级


        1.0 实现冒泡排序

        冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的元素,并交换它们直到列表排序完成。冒泡排序的时间复杂度为 O(n^2) ,在最坏的情况下需要进行 n*(n-1)/2 次比较和交换操作。是一个稳定排序。

具体步骤如下:

         -从列表的第一个元素开始,依次比较相邻的两个元素,如果它们的顺序不正确,则交换它们的位置。

        - 继续比较相邻的元素,直到达到列表的末尾。

        - 重复以上步骤,直到列表排序完成。

冒泡排序的详解过程:

        冒泡排序的过程可以用一个简单的示意图来说明,假设我们要对一个包含5个元素的列表进行冒泡排序:

        初始状态: [5, 3, 8, 2, 1]

        第一轮冒泡:比较相邻的元素并交换它们的位置,直到最大的元素被“冒泡”到列表的末尾。[3, 5, 2, 1, 8] ,[x, x, x, x, 8] 所在的位置就是最终的位置,因此不需要再进行交换了。

        第二轮冒泡:同样比较相邻的元素并交换它们的位置,直到最大的元素被“冒泡”到列表的末尾。[3, 2, 1, 5, 8] , [x, x, x, 5, 8] 所在的位置就是最终的位置,因此不需要再进行交换了。

        第三轮冒泡:同理,[2, 1, 3, 5, 8] , [x, x, 3, 5, 8] 所在的位置就是最终的位置,因此不需要再进行交换了。

        第四轮冒泡:[1, 2, 3, 5, 8] 完成排序了,一共需要进行(数组长度 - 1 )轮冒泡。

        

  数组的顺序为 [8,7,6,5,4,3,2,1] 来进行冒泡排序的动态演示过程:

        

代码如下:

import java.util.Arrays;public class BubbleSort {public static void main(String[] args) {int[] arr = {1,10,7,4,8,3,2,6,9,5};bubble(arr);System.out.println(Arrays.toString(arr));}//冒泡排序public static void bubble(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;}}}}
}

        2.0 实现选择排序

        选择排序(Selection Sort)是一种简单直观的排序算法。选择排序的时间复杂度为 O(n^2) ,因为在每一轮中需要进行n次比较,找到最小元素。(默认从小到大排序)

       基本思想:每次从待排序的数据元素中选出最小(或最大)的一个元素,然后放到已排序序列的末尾。内层循环代表的是:当前这次循环中,需要找到剩余数组中最小的元素;外层循坏代表的是:需要进行多少次内层循环,才能将数组中的元素按从小到大排序完成。

举例详解选择过程:

        初识状态:[3, 44, 5, 27, 2, 50, 48]

        第一轮选择过程:记录未排好序的元素 3 ,然后从元素 3 的后一个元素 44 出发,寻找比 3 小的元素,如果找到了,则需要进行交换;如果没有找到,这说明元素 3 就是当前循环过程中最小的元素。当前找到了比元素 3 小的元素 2 ,那么需要进行交换。

        第二轮选择过程:因为元素 2 已经排好序了,那么需要记录从排好序元素的后一个元素 44 ,寻找的范围是当前记录的元素的后一个元素开始出发直到数组最后一个元素。同样,重复以上操作,如果找到了比 44 要小的元素,需要进行记录 minIndex = i ,内层循环结束后,最小的元素下标为 minIndex  ,交换 44 与下标为 minIndex 的元素。

        第三轮选择过程也是一样流程,这里就不多赘述了......

选择过程的动态图演示过程:

代码如下:

import java.util.Arrays;public class SelectSort {public static void main(String[] args) {int[] arr = {1,10,7,4,8,3,2,6,9,5};select1(arr);System.out.println(Arrays.toString(arr));}public static void select1(int[] arr) {for (int i = 0;i < arr.length - 1;i++) {int minIndex = i;for (int j = i + 1;j < arr.length;j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}if (i != minIndex) {swap(arr,i,minIndex);}}}public static void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}

        2.1 选择排序的改良升级

        在选择过程中,内层循环每一次都是寻找最小的元素,这次改进是在寻找最小元素的同时,又找最大的元素,定义两个 letf ,right 指针,一开始分别指向数组的左右两边。此时外层的循环条件:left < right 。一次内层循环中找到了最小、最大元素,接着就分别于 left、right 下标元素进行交换,交换完之后,left++ ,right-- 。

        一开始 minIndex、maxIndex 都是从 left 开始,从左到右进行查找元素的。重点需要需要注意的是:假如最大的元素就是当前的 left 下标时,且 minIndex 与 left 进行交换后,会导致 maxIndex 找的元素下标就会发生变化,所以在下标 minIndex 与 left 交换完之后,需要判断 maxInde == left 是否发生,如果发生了,那么 maxIndex 需要重新赋值为 maxIndex = minIndex 。

代码如下:

import java.util.Arrays;public class SelectSort {public static void main(String[] args) {int[] arr = {1,10,7,4,8,3,2,6,9,5};select2(arr);System.out.println(Arrays.toString(arr));}public static void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}public static void select2(int[] arr) {int left = 0;int right = arr.length-1;while (left < right) {int minIndex = left;int maxIndex = left;for (int i = left+1;i <= right; i++) {if (arr[i] < arr[minIndex]) {minIndex = i;}if (arr[i] > arr[maxIndex]) {maxIndex = i;}}swap(arr,minIndex,left);if (maxIndex == left) {maxIndex = minIndex;}swap(arr,maxIndex,right);left++;right--;}}}

        3.0 实现堆排序

        堆排序(Heap Sort)是一种高效的排序算法,它利用了堆这种数据结构来实现排序。堆是一种特殊的完全二叉树,分为最大堆和最小堆两种类型。在堆排序中,通常使用最大堆。堆排序的时间复杂度为 O(nlogn) ,并且是原地排序算法,不需要额外的存储空间。

        堆排序的基本思想:首先将待排序的数据构建成一个最大堆,然后将堆顶元素(最大元素)与堆的最后一个元素交换,然后对剩余的元素重新调整为最大堆,重复这个过程直到整个序列有序。

        两个动作:首先是将数组中的元素构建成一个大顶堆的形式,接着从堆的最后一个元素与堆顶元素进行交换,再对当前的堆顶元素进行下潜处理,循环该过程即可。

堆排序的动态演示过程:(该过程演示的是降序的排序过程,那么相反,建立一个小顶堆)

代码如下:

建立大顶堆的代码:下潜、交换元素

class Heap {int[] arr;int size = 0;public Heap(int[] arr) {this.arr = arr;this.size = arr.length;buildBigHeap(arr,size);heapSort(arr);}public void buildBigHeap(int[] arr,int size) {for (int i = size / 2 - 1; i >= 0 ; i--) {down(i,size);}}private void down(int i,int size) {int left = i * 2 + 1;int right = left + 1;int max = i;if (left < size && arr[max] < arr[left]) {max = left;}if (right < size && arr[max] < arr[right]) {max = right;}if (max != i) {swap(arr,max,i);down(max,size);}}private void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}

堆排序的完整代码:

import java.util.Arrays;public class HeapSort {public static void main(String[] args) {int[] arr = {1,10,7,4,8,3,2,6,9,5};Heap heap = new Heap(arr);System.out.println(Arrays.toString(arr));}
}
class Heap {int[] arr;int size = 0;public Heap(int[] arr) {this.arr = arr;this.size = arr.length;buildBigHeap(arr,size);heapSort(arr);}public void buildBigHeap(int[] arr,int size) {for (int i = size / 2 - 1; i >= 0 ; i--) {down(i,size);}}private void down(int i,int size) {int left = i * 2 + 1;int right = left + 1;int max = i;if (left < size && arr[max] < arr[left]) {max = left;}if (right < size && arr[max] < arr[right]) {max = right;}if (max != i) {swap(arr,max,i);down(max,size);}}private void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}public void heapSort(int[] arr) {for (int i = arr.length - 1; i > 0 ; i--) {swap(arr,i,0);down(0,i);}}}

        4.0 实现插入排序

        插入排序是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对未排序的数据逐个进行插入,从而达到排序的目的。插入排序的时间复杂度为 O(n^2) ,在最坏情况下(逆序排列的数组),需要进行 n*(n-1)/2 次比较和交换操作。插入排序适用于小规模数据或部分有序的数据。是一个稳定排序。

具体来说,插入排序的算法步骤如下:

        1.从第一个元素开始,该元素可以认为已经被排序。

        2.取出下一个元素,在已经排序的元素序列中从后向前扫描。

        3.如果该元素(已排序)大于新元素,将该元素移到下一位置。

        4.重复步骤3,直到找到已排序的元素小于或等于新元素的位置。

        5.将新元素插入到该位置后。

        6.重复步骤2~5。

插入排序动态图演示过程:

代码如下:

import java.util.Arrays;public class InsertSort {public static void main(String[] args) {int[] arr = {1,10,7,4,8,3,2,6,9,5};insert(arr);System.out.println(Arrays.toString(arr));}public static void insert(int[] arr) {for (int i = 1; i < arr.length; i++) {int key = arr[i];int j = i - 1;while(j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}}}

        5.0 实现希尔排序

        希尔排序(Shell Sort)是一种改进的插入排序算法,也被称为“缩小增量排序”。它通过将数组分割成若干个子序列,对每个子序列进行插入排序,最终进行一次完整的插入排序得到有序序列。希尔排序的工作原理是通过逐步减小增量的方式,最终达到增量为1的插入排序。希尔排序的时间复杂度取决于增量序列的选择,通常为 O(n logn)

希尔排序的算法步骤如下:

        1. 选择一个增量序列,通常为 n/2、n/4、n/8……直到增量为 1 。

        2. 对每个增量进行插入排序,即将数组分割成若干个子序列,对每个子序列进行插入排序。

        3. 逐步缩小增量,重复步骤 2 ,直到增量为 1 。

        4. 最后进行一次增量为 1 的插入排序,完成排序过程。

希尔排序的动态演示过程:

代码如下:

import java.util.Arrays;public class ShellSort {public static void main(String[] args) {int[] arr = {8,9,1,7,2,3,5,4,6,0};shell(arr);System.out.println(Arrays.toString(arr));}public static void shell(int[] arr) {int size = arr.length;for (int gap = size >> 1;gap >= 1; gap >>= 1) {for (int i = gap; i < size;i++) {int key = arr[i];int j = i-gap;while(j >= 0 && arr[j] > key) {arr[j+gap] = arr[j];j -= gap;}arr[j + gap] = key;}}}}

        6.0 实现归并排序

        归并排序(Merge Sort)是一种经典的分治算法,它的基本思想是将待排序的数组递归地分成两个子数组,分别对两个子数组进行排序,然后将两个已排序的子数组合并成一个有序的数组。归并排序的过程可以描述为“分而治之”。

        归并排序是一种稳定的排序算法,它的时间复杂度始终为 O(n log n) ,这使得它在处理大规模数据时具有较好的性能。然而,归并排序的空间复杂度较高,因为它需要额外的空间来存储临时数组。

        6.1 递归实现归并排序

归并排序的算法步骤如下:

        1. 分:将待排序的数组分成两个子数组,直到子数组的长度为1。

        2. 治:对每个子数组进行递归排序,直到子数组有序。

        3. 合:将两个有序的子数组合并成一个有序的数组。

使用递归实现归并的动态演示过程:

代码如下:

import javax.print.DocFlavor;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.IllegalFormatCodePointException;public class mergeSort {public static void main(String[] args) {int[] arr = {1,10,7,4,8,3,2,6,9,5};int[] a = new int[arr.length];//spilt(arr,0, arr.length - 1,a);//merge(arr);spiltInsert(arr,0,arr.length,a);System.out.println(Arrays.toString(arr));}//使用递归实现归并排序public static void spilt(int[] arr,int left,int right, int[] a) {if (left == right) {return;}//分int mid = (left + right) >>> 1;spilt(arr,left,mid,a);spilt(arr,mid+1,right,a);//合mergeArr(arr,left,mid,mid + 1,right,a);System.arraycopy(a,left,arr,left,right - left + 1);}//非递归实现两个有序数组合并public static void mergeArr(int[] arr,int i,int iEnd,int j,int jEnd,int[] a) {int k = i;while(i <= iEnd && j <= jEnd) {if (arr[i] < arr[j]) {a[k] = arr[i];i++;}else {a[k] = arr[j];j++;}k++;}if (i > iEnd) {System.arraycopy(arr,j,a,k,jEnd - j + 1);}if (j > jEnd) {System.arraycopy(arr,i,a,k,iEnd - i + 1);}}}

         6.2 使用非递归实现归并排序

        非递归归并排序的关键是正确地计算子数组的大小并进行合并操作,直到整个数组都被合并为一个有序序列。

以下是非递归归并排序的主要步骤:

        1. 从数组中的每个元素开始,将其视为一个大小为1的有序序列。

        2. 通过迭代,将相邻的有序序列合并为更大的有序序列,直到整个数组变为一个有序序列。

        3. 在每次迭代中,合并的子数组大小以指数级增加,直到整个数组都被合并为一个有序序列。

代码如下:

    //使用非递归实现归并排序public static void merge(int[] arr) {int n = arr.length;;int[] a = new int[n];for (int width = 1;width < n ;width *= 2) {//[left,right] 分别代表带合并区间的左右边界for (int left = 0;left < n; left = left + 2 * width) {int right = Math.min(left + 2 * width - 1,n - 1);int m = Math.min(left + width - 1,n - 1);mergeArr(arr,left,m,m+1,right,a);}System.arraycopy(a,0,arr,0,n);}}//非递归实现两个有序数组合并public static void mergeArr(int[] arr,int i,int iEnd,int j,int jEnd,int[] a) {int k = i;while(i <= iEnd && j <= jEnd) {if (arr[i] < arr[j]) {a[k] = arr[i];i++;}else {a[k] = arr[j];j++;}k++;}if (i > iEnd) {System.arraycopy(arr,j,a,k,jEnd - j + 1);}if (j > jEnd) {System.arraycopy(arr,i,a,k,iEnd - i + 1);}}

        6.3 递归归并排序 + 插入排序

        即集合了递归排序的优点与插入排序的优点实现更加高效排序。

代码如下:

    //递归归并 + 插入排序public static void spiltInsert(int[] arr,int left,int right,int[] a) {if (right - left <= 32) {insert(arr,left,right);return;}int m = (left + right) >>> 1;spiltInsert(arr,left,m,a);spiltInsert(arr,m+1,right,a);mergeArr(arr,left,m,m+1,right,a);System.arraycopy(a,left,arr,left,right-left+1);}//插入排序public static void insert(int[] arr,int left, int right) {for (int i = left + 1; i < right; i++) {int key = arr[i];int j = i - 1;while (j >= left && arr[j] > key) {arr[j+1] = arr[j];j--;}arr[j+1] = key;}}

        7.0 快速排序

        快速排序是一种常用的排序算法,它基于分治的思想。快速排序的基本思想是选择一个基准值,然后将数组分割成两部分,使得左边的元素都小于基准值,右边的元素都大于基准值。然后对左右两部分分别进行递归排序,直到整个数组有序。

以下是快速排序的主要步骤:

        1.选择一个基准值(通常是数组中的第一个元素)。

        2.将数组分割成两部分,使得左边的元素都小于基准值,右边的元素都大于基准值。这一步称为分区操作。

        3. 递归地对左右两部分进行快速排序。

        4. 当左右两部分都有序时,整个数组也就有序了。

        7.1 单边循环快排

        单边循环快排的时间复杂度为 O(n logn)空间复杂度为 O(logn)。单边循环快排(也称为荷兰国旗问题解法)是快速排序算法的一种实现方式,它通过使用单个指针在数组中进行循环遍历,实现数组的分区和排序。

代码如下:

//单边循环快排要点://选择最右侧元素作为基准点//j 找比基准点小的,i 找基准点大的,一旦找到,二者进行交换://                   交换时机: j 找到小的,且与 i 不相等//                   i 找到 >= 基准点元素后,不应自增// 最后基准点与 i 交换, i 即为基准点最终索引public static void quickSort(int[] arr) {recursion(arr,0,arr.length-1);}private static void recursion(int[] arr,int left,int right) {if (left >= right) {return;}//先找到基准点int m = benchmark(arr,left,right);//切分基准点两侧recursion(arr, left, m - 1);recursion(arr, m + 1, right);}private static int benchmark(int[] arr,int left,int right) {int temp = arr[right];//i 找最大值、 j 找最小值,一旦 j 找到最小值且 j != i 就可以交换了int i = left;int j = left;while (j < right) {if (arr[j] < temp) {if (i != j) {//交换swap(arr,i,j);}i++;}j++;}swap(arr,i,right);return i;}private static void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}

        7.2 双边循环快排

        双边循环快排是一种快速排序算法的实现方式,它通过不断地将数组分割成两部分并对每一部分进行递归排序来实现排序。与单边循环快排相比,双边循环快排在分割数组时使用两个指针分别从数组的两端向中间移动,以实现更高效的分割操作。

        双边循环快排的时间复杂度为 O(nlogn)空间复杂度为 O(logn)。它是一种高效的排序算法,在大多数情况下都能够快速地对数组进行排序。

具体实现过程如下:

        1. 选择数组中的一个元素作为基准值(通常选择第一个元素)。

        2. 设置两个指针,一个指向数组的起始位置,另一个指向数组的末尾位置。

        3. 从起始位置开始,找到第一个大于基准值的元素,并将其位置记录下来。

        4. 从末尾位置开始,找到第一个小于基准值的元素,并将其位置记录下来。

        5. 交换这两个元素的位置,然后继续寻找下一个需要交换的元素,直到两个指针相遇。

        6. 将基准值与指针相遇的位置的元素交换位置,这样基准值左边的元素都小于基准值,右边的元素都大于基准值。

        7. 对基准值左右两个子数组分别进行递归排序。

代码如下:

    //双边循环快排要点://选择最左侧元素作为基准点//j 找比基准点小的, i 找比基准点大的,一旦找到,二者进行交换//       i 从左向右//       j 从右先左// 最后基准点与 i 交换, i 即为基准点最终索引public static void quickSort1(int[] arr) {recursion1(arr,0,arr.length-1);}private static void recursion1(int[] arr,int left,int right) {if (left >= right) {return;}int m = benchmark1(arr,left,right);recursion1(arr,left,m - 1);recursion1(arr,m + 1,right);}private static int benchmark1(int[] arr,int left,int right) {int temp = arr[left];int i = left;int j = right;while (i < j) {while (i < j && temp < arr[j]) {j--;}while (i < j && temp >= arr[i]) {i++;}swap(arr,i,j);}swap(arr,left,i);return i;}private static void swap(int[] arr,int i,int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}

        7.3 快速排序的改良升级

        考虑快排时,遇到的重复元素过多而进行改良。

代码如下:

    public static void quickSort1(int[] arr) {recursion1(arr,0,arr.length-1);}private static void recursion1(int[] arr,int left,int right) {if (left >= right) {return;}int m = benchmark2(arr,left,right);recursion1(arr,left,m - 1);recursion1(arr,m + 1,right);}//考虑快排时,遇到的重复元素过多而进行改良private static int benchmark2(int[] arr,int left,int right) {int temp = arr[left];int i = left + 1;int j = right;while(i <= j) {while(i <= j && arr[i] < temp) {i++;}while (i <= j && arr[j] > temp ) {j--;}if (i <= j) {swap(arr,i,j);i++;j--;}}swap(arr,left,j);return j;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/269351.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用FPGA CORDIC IP核实现信号的相位检测,计算相位角

用FPGA CORDIC IP核实现信号的相位检测 1.matlab仿真 波形仿真代码&#xff1a; 代码功能&#xff1a;生成一个点频信号s&#xff0c;求出s的实部和虚部&#xff1b;并且结算相位角atan2。画出图形&#xff0c;并且将Q和I数据写入文件中。 %代码功能&#xff1a;生成一个点…

双链表——“数据结构与算法”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰又回来了&#xff0c;到了好久没有更新的数据结构与算法专栏&#xff0c;最近确实发现自己有很多不足&#xff0c;需要学习的内容也有很多&#xff0c;所以之后更新文章可能不会像之前那种一天一篇或者一天两篇啦&…

红帆OA 多处 SQL注入漏洞复现

0x01 产品简介 红帆iOffice.net从最早满足医院行政办公需求(传统OA),到目前融合了卫生主管部门的管理规范和众多行业特色应用,是目前唯一定位于解决医院综合业务管理的软件,是最符合医院行业特点的医院综合业务管理平台,是成功案例最多的医院综合业务管理软件。 0x02 漏…

网络安全: Kali Linux 使用 docker-compose 部署 openvas

目录 一、实验 1.环境 2.Kali Linux 安装docker与docker-compose 3.Kali Linux 使用docker-compose方式部署 openvas 4. KaliLinux 使用openvas 二、问题 1. 信息安全漏洞库 2.信息安全漏洞共享平台 3.Windows 更新指南与查询 4.CVE 查询 5.docker-compose 如何修改o…

哪些型号的高速主轴适合PCB分板机

在选择适合PCB分板机的高速主轴时&#xff0c;SycoTec品牌提供了丰富的型号选择&#xff0c;主要型号包括4025 HY、4033 AC&#xff08;电动换刀&#xff09;、4033 AC-ESD、4033 DC-T和4041 HY-ESD等。 那么如何选择合适的PCB分板机高速主轴型号呢&#xff1f;在选择适合PCB分…

LZO索引文件失效说明

在hive中创建lzo文件和索引时&#xff0c;进行查询时会出现问题.hive的默认输入格式是开启小文件合并的&#xff0c;会把索引也合并进来。所以要关闭hive小文件合并功能&#xff01;

day03_Vue_Element

文章目录 01.Ajax1.1 Ajax 概述1.2 同步异步1.3 原生Ajax 2. Axios2.1 Axios的基本使用2.2 Axios快速入门2.3请求方法的别名2.4 案例 3 前后台分离开发3.1 前后台分离开发介绍 04 YAPI4.1 YAPI介绍4.2 接口文档管理 05 前端工程化5.1 前端工程化介绍5.2 前端工程化入门5.2.1 环…

小程序学习

1、小程序体验 2、注册账号 小程序 (qq.com) 3、开发工具下载 下载 / 稳定版更新日志 (qq.com) 4、目录结构 "navigationBarBackgroundColor": "#00b26a" 配置头部背景色 4、wxml模板介绍 5、wxss 6、js文件 7、宿主环境 1、通信主体 2、运行机制 3、…

网工学习 DHCP配置-接口模式

网工学习 DHCP配置-接口模式 学习DHCP总是看到&#xff0c;接口模式、全局模式、中继模式。理解起来也不困难&#xff0c;但是自己动手操作起来全是问号。跟着老师视频配置啥问题没有&#xff0c;自己组建网络环境配置就是不通&#xff0c;悲催。今天总结一下我学习接口模式的…

动手学深度学习—循环神经网络RNN详解

循环神经网络 循环神经网络的步骤&#xff1a; 处理数据 将数据按照批量大小和时间步数进行处理&#xff0c;最后得到迭代器&#xff0c;即每一个迭代的大小是批量大小时间步数&#xff0c;迭代次数根据整个数据的大小决定&#xff0c;最后得出处理的数据&#xff08;参照第三…

基于SpringBoot的物业管理系统

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1 研究…

Elasticsearch:使用 Streamlit、语义搜索和命名实体提取开发 Elastic Search 应用程序

作者&#xff1a;Camille Corti-Georgiou 介绍 一切都是一个搜索问题。 我在 Elastic 工作的第一周就听到有人说过这句话&#xff0c;从那时起&#xff0c;这句话就永久地印在了我的脑海中。 这篇博客的目的并不是我出色的同事对我所做的相关陈述进行分析&#xff0c;但我首先…

Python的PrettyTable模块

Python的PrettyTable模块 1.PrettyTable介绍与基本使用 ​ 在使用Python查询表格数据的时候&#xff0c;直接print出来的话。数据杂乱无章&#xff0c;这个使用就可以使用PrettyTable模块来解决这个问题。如下图: 这样在输出的窗口可以很清晰看到所需要的信息。那么类似这种表…

更换个人开发环境后,pycharm连接服务器报错Authentication failed

原因&#xff1a;服务器中更换个人开发环境后&#xff0c;密码变了。 解决&#xff1a;在pycharm中修改服务器开发环境密码即可。 1 找到Tools-Depolyment-Configuration 2 点击SSH Configuration后的省略号 3 修改这里面的Password即可

autodock分子对接操作步骤完整版

对接完整步骤具体操作 设置工作目录 保证工作目录下必须要有这五个文件&#xff1a; 对蛋白质的操作 打开蛋白质 去水&#xff0c;结构周围的小红点。 加氢 将蛋白质设为受体 点击确定进行保存 进行下一步小分子 小分子具体操作 打开小分子 对小分子进行加氢 将小分子设定为配…

第三篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas股票市场数据分析

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas进行股票市场数据分析常见步骤和示例代码1. 加载数据2. 数据清洗和准备3. 分析股票价格和交易量4. 财务数据分析 二、扩展思路介绍1. 技术指标分析2. 波动性分析3. 相关性分析4.…

HTML5:七天学会基础动画网页7

CSS3高级特效 2D转换方法 移动:translate() 旋转:rotate() 缩放:scale() 倾斜:skew() 属性:transform 作用:对元素进行移动,旋转,缩放,倾斜。 2D移动 设定元素从当前位置移动到给定位置(x,y) 方法 说明 translate(x,y) 2D转换 沿X轴和Y轴移…

【李沐论文精读】Transformer精读

论文&#xff1a;Attention is All You Need 参考&#xff1a;李沐视频【Transformer论文逐段精读】、Transformer论文逐段精读【论文精读】、李沐视频精读系列 一、摘要 主流的序列转换(sequence transduction)模型都是基于复杂的循环或卷积神经网络&#xff0c;这个模型包含一…

云计算,用价格让利换创新空间?

文 | 智能相对论 作者 | 李源 ECS&#xff08;云服务器&#xff09;最高降36%、OSS&#xff08;对象存储&#xff09;最高降55%、RDS&#xff08;云数据库&#xff09;最高降40%…… 阿里云惊人的降幅&#xff0c;一次性把国内云计算厂商的价格战推到了白热化阶段。 这次能…

LVS负载均衡集群的基本介绍

目录 一、LVS集群基本介绍 1、什么是集群 2、集群的类型 2.1 负载均衡群集&#xff08;Load Balance Cluster) 2.2 高可用群集(High Availiablity Cluster) 2.3 高性能运算群集(High Performance Computing Cluster) 3、负载均衡集群的结构 4、LVS集群类型中的术语 5、…