常用算法之排序(Java)
第1次遍历,将索引为0的元素与索引大于0的所有元素进行比较找到最小的元素,将最小元素与索引为0的元素交换位置(若索引为0的元素就是最小元素那么它就和自己交换)
第2次遍历,将索引为1的元素与索引大于1的所有元素进行比较找到最小的元素,将最小元素与索引为1的元素交换位置(若索引为1的元素就是最小元素那么它就和自己交换)。
如此往复,直到将整个数组排好序。
优点:数据交换次数最少的,与数组大小是线性关系,只有N次,别的排序算法大部分的增长数量级都是线性对数或平方级别
缺点:运行时间和输入无关。如,两个长度都为N的数组,一个元素顺序随机的数组,另一个已排好序或所有元素相等的数组,他们的排序时间一样长。
@SuppressWarnings("unchecked")
public class Selection
{
// This class should not be instantiated.
private Selection() { } public static void sort(Comparable[] a)
{
// in ascending order
int N = a.length;
for(int i = 0;i < N;i++)
{
// exchange elements
int min = i;
for(int j= i+1;j < N;j++)
{
// find the index of the smallest element
if(less(a[j], a[min]))
{
min = j;
}
}
exch(a, i, min);
} } // is v < w ?
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
} // exchange a[i] and a[j]
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
} // print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println("");
} public static void main(String[] args) {
Comparable[] a = {3,5,2,1,7,4,6};
Selection.sort(a);
show(a);
}
}
原理:就像现实中玩扑克牌一样,一张一张的来,将每一张牌插入到其他已经有序的牌中的适当的位置。为了给要插入的元素腾出空间,需将其余所有元素在插入前向右移动一位。
原始数据有序性越高,插入排序越快。
平均情况下:插入排序需要N*N/4次比较和N*N/4次交换
最坏情况下:插入排序需要N*N/2次比较和N*N/2次交换(逆序数组)
最好情况下:插入排序需要N-1次比较和0次交换(已排好序的数组)
优点:插入排序运行时间取决于数组元素初始顺序。如,使用插入排序对一个很大且其中的元素已有序(或接近有序)的数组进行排序将会比对随机顺序的数组或逆序数组进行排序要快的多
缺点:比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候
适用场景:插入排序对部分有序的数组十分高效,也很适合小规模数组
@SuppressWarnings("unchecked")
public class Insertion
{
// This class should not be instantiated.
private Insertion() { } public static void sort(Comparable[] a)
{
// in ascending order
int N = a.length;
for(int i = 1;i < N;i++)
{
// exchange elements
for(int j= i;j > 0 && less(a[j],a[j -1]);j--)
{
exch(a, j, j-1);
}
} } // less()、show()、exch()和main()方法见Selection.java
}
缺点:h乘以的常数因子只能凭经验来设置,不太稳定
适用场景:大规模乱序数组
@SuppressWarnings("unchecked")
public class Shell
{
// This class should not be instantiated.
private Shell() { } public static void sort(Comparable[] a)
{
// in ascending order
int N = a.length;
// 3x+1 increment sequence: 1, 4, 13, 40, 121, 364, 1093, ...
int h = 1;
while (h < N/3) {
h = 3*h + 1;
}
while (h >= 1) {
// h-sort the array
for (int i = h; i < N; i++) {
for (int j = i; j >= h && less(a[j], a[j -h]); j -= h) {
exch(a,j, j-h);
}
}
h /= 3;
}
} // less()、show()、exch()和main()方法见Selection.java
}
原理:要将一个数组排序,可先(递归的)将它等分成两半分别排序,然后将结果归并起来。递归发生在处理整个数据之前。
缺点:实现比较复杂,排序需要额外空间且它所需的额外空间和N成正比
适用场景:稳定性很重要而空间不是问题时,归并排序可能是最好的
@SuppressWarnings("unchecked")
public class Merge
{
// This class should not be instantiated.
private Merge() { } /**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
Comparable[] aux = new Comparable[a.length];
sort(a, aux, 0, a.length-1);
} // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
private static void sort(Comparable[] a, Comparable[] aux, int lo, int hi) {
if (hi <= lo) return;
int mid = lo + (hi - lo) / 2;
sort(a, aux, lo, mid);
sort(a, aux, mid + 1, hi);
merge(a, aux, lo, mid, hi);
} // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
private static void merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi) {
// copy to aux[]
for (int k = lo; k <= hi; k++) {
aux[k] = a[k];
} // merge back to a[]
int i = lo, j = mid+1;
for (int k = lo; k <= hi; k++) {
if (i > mid){
a[k] = aux[j++];
} else if (j > hi) {
a[k] = aux[i++];
} else if (less(aux[j], aux[i])) {
a[k] = aux[j++];
} else {
a[k] = aux[i++];
}
}
} // less()、show()、exch()和main()方法见Selection.java
}
原理:与归并排序不同之处是快速排序切分(partition)的位置取决于数组的内容而归并排序是等分成两半。先将一个数组切分成两个子数组,然后将两部分独立排序。递归发生在处理整个数组之后。
优点:实现简单,原地排序且将长度为N的数组排序所需的时间和NlgN成正比
缺点:非常脆弱,实现时要非常小心才能避免低劣的性能,多种错误能使它在实际中的性能只有平方级别
适用场景:适用无重复元素的数组排序。运行时间至关重要而稳定性要求不是很高时,快速排序可能是最好的
@SuppressWarnings("unchecked")
public class Quick
{
// This class should not be instantiated.
private Quick() { } /**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
// 打乱数组,保证随机性。这对预测算法的运行时间很重要
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
} // quicksort the subarray from a[lo] to a[hi]
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int j = partition(a, lo, hi);
sort(a, lo, j-1);
sort(a, j+1, hi);
} // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
// and return the index j.
private static int partition(Comparable[] a, int lo, int hi) {
int i = lo;
int j = hi + 1;
Comparable v = a[lo];
while (true) { // find item on lo to swap
while (less(a[++i], v)) {
if (i == hi) break;
} // find item on hi to swap
while (less(v, a[--j])) {
if (j == lo) break; // redundant since a[lo] acts as sentinel
} // check if pointers cross
if (i >= j) break; exch(a, i, j);
} // put partitioning item v at a[j]
exch(a, lo, j); // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
return j;
} // less()、show()、exch()和main()方法见Selection.java
}
import java.util.Random;
public final class StdRandom { private static Random random; // pseudo-random number generator
private static long seed; // pseudo-random number generator seed // static initializer
static {
// this is how the seed was set in Java 1.4
seed = System.currentTimeMillis();
random = new Random(seed);
} // don't instantiate
private StdRandom() { } /**
* Returns a random real number uniformly in [0, 1).
*
* @return a random real number uniformly in [0, 1)
*/
public static double uniform() {
return random.nextDouble();
} /**
* Returns a random integer uniformly in [0, n).
*
* @param n number of possible integers
* @return a random integer uniformly between 0 (inclusive) and {@code n} (exclusive)
* @throws IllegalArgumentException if {@code n <= 0}
*/
public static int uniform(int n) {
if (n <= 0) throw new IllegalArgumentException("argument must be positive: " + n);
return random.nextInt(n);
} /**
* Returns a random long integer uniformly in [0, n).
*
* @param n number of possible {@code long} integers
* @return a random long integer uniformly between 0 (inclusive) and {@code n} (exclusive)
* @throws IllegalArgumentException if {@code n <= 0}
*/
public static long uniform(long n) {
if (n <= 0L) throw new IllegalArgumentException("argument must be positive: " + n);
long r = random.nextLong();
long m = n - 1; // power of two
if ((n & m) == 0L) {
return r & m;
} // reject over-represented candidates
long u = r >>> 1;
while (u + m - (r = u % n) < 0L) {
u = random.nextLong() >>> 1;
}
return r;
} /**
* Returns a random integer uniformly in [a, b).
*
* @param a the left endpoint
* @param b the right endpoint
* @return a random integer uniformly in [a, b)
* @throws IllegalArgumentException if {@code b <= a}
* @throws IllegalArgumentException if {@code b - a >= Integer.MAX_VALUE}
*/
public static int uniform(int a, int b) {
if ((b <= a) || ((long) b - a >= Integer.MAX_VALUE)) {
throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")");
}
return a + uniform(b - a);
} /**
* Returns a random real number uniformly in [a, b).
*
* @param a the left endpoint
* @param b the right endpoint
* @return a random real number uniformly in [a, b)
* @throws IllegalArgumentException unless {@code a < b}
*/
public static double uniform(double a, double b) {
if (!(a < b)) {
throw new IllegalArgumentException("invalid range: [" + a + ", " + b + ")");
}
return a + uniform() * (b-a);
} /**
* Rearranges the elements of the specified array in uniformly random order.
*
* @param a the array to shuffle
* @throws IllegalArgumentException if {@code a} is {@code null}
*/
public static void shuffle(Object[] a) {
validateNotNull(a);
int n = a.length;
for (int i = 0; i < n; i++) {
int r = i + uniform(n-i); // between i and n-1
Object temp = a[i];
a[i] = a[r];
a[r] = temp;
}
} /**
* Rearranges the elements of the specified array in uniformly random order.
*
* @param a the array to shuffle
* @throws IllegalArgumentException if {@code a} is {@code null}
*/
public static void shuffle(double[] a) {
validateNotNull(a);
int n = a.length;
for (int i = 0; i < n; i++) {
int r = i + uniform(n-i); // between i and n-1
double temp = a[i];
a[i] = a[r];
a[r] = temp;
}
} /**
* Rearranges the elements of the specified array in uniformly random order.
*
* @param a the array to shuffle
* @throws IllegalArgumentException if {@code a} is {@code null}
*/
public static void shuffle(int[] a) {
validateNotNull(a);
int n = a.length;
for (int i = 0; i < n; i++) {
int r = i + uniform(n-i); // between i and n-1
int temp = a[i];
a[i] = a[r];
a[r] = temp;
}
} /**
* Rearranges the elements of the specified array in uniformly random order.
*
* @param a the array to shuffle
* @throws IllegalArgumentException if {@code a} is {@code null}
*/
public static void shuffle(char[] a) {
validateNotNull(a);
int n = a.length;
for (int i = 0; i < n; i++) {
int r = i + uniform(n-i); // between i and n-1
char temp = a[i];
a[i] = a[r];
a[r] = temp;
}
} // throw an IllegalArgumentException if x is null
// (x can be of type Object[], double[], int[], ...)
private static void validateNotNull(Object x) {
if (x == null) {
throw new IllegalArgumentException("argument is null");
}
} /**
* Unit tests the methods in this class.
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
String[] a = "A B C D E F G".split(" ");
StdRandom.shuffle(a);
for (String s : a){
System.out.print(" "+s);
}
System.out.println("");
} }
原理:从左到右遍历数组一次,维护3个指针。一个指针lt,使得a[lo..lt-1]中的元素都小于v;一个指针gt,使得a[gt+1..hi]中的元素都大于v;一个指针i,使得a[lt..i-1]中的元素都等于v;a[i..gt]中的元素都还未确定。
缺点:数组中重复元素不多时比标准的二分法多使用很多次交换,最坏的情况是所有元素均不重复时
适用场景:适用大量重复元素的数组排序,如企业可能需要将大量人员资料按照生日或性别排序
@SuppressWarnings("unchecked")
public class Quick3Way
{
// This class should not be instantiated.
private Quick3Way() { } /**
* Rearranges the array in ascending order, using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
StdRandom.shuffle(a);
sort(a, 0, a.length - 1);
} // quicksort the subarray a[lo .. hi] using 3-way partitioning
private static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) return;
int lt = lo, i = lo + 1, gt = hi;
Comparable v = a[lo];while (i <= gt) {
int cmp = a[i].compareTo(v);
if (cmp < 0) {
exch(a, lt++, i++);
} else if (cmp > 0) {
exch(a, i, gt--);
} else {
i++;
}
} // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi].
sort(a, lo, lt-1);
sort(a, gt+1, hi);
} // less()、show()、exch()和main()方法见Selection.java
}
原理:堆排序分两个阶段:堆的构造阶段和下沉排序阶段。
缺点:无法利用缓存,数组元素很少和相邻的其他元素进行比较,因此缓存未命中的次数要远高于大多数比较都在相邻元素间进行的排序算法(如快速排序、归并排序、希尔排序等)
适用场景:插入操作和删除最大元素操作混合的动态场景(此时运行时间能保证是对数级别的)
@SuppressWarnings("unchecked")
public class Heap
{
// This class should not be instantiated.
private Heap() { } /**
* Rearranges the array in ascending order, using the natural order.
* @param pq the array to be sorted
*/
public static void sort(final Comparable[] pq) {
int n = pq.length;
for (int k = n/2; k >= 1; k--){
sink(pq, k, n);
}
while (n > 1) {
exch(pq, 1, n--);
sink(pq, 1, n);
}
} /***************************************************************************
* Helper functions to restore the heap invariant.
***************************************************************************/ private static void sink(Comparable[] pq, int k, int n) {
while (2*k <= n) {
int j = 2*k;
if (j < n && less(pq[j-1], pq[j])){
j++;
}
if (!less(pq[k-1], pq[j-1])) {
break;
}
exch(pq, k, j);
k = j;
}
} // less()、show()、exch()和main()方法见Selection.java
}
二.实际应用中如何选择何种算法
Java的系统程序员对原始数据类型使用(三向切分的)快速排序(速度快),对引用类型使用归并排序(稳定性高)。见Array.sort()实现
总结:实际应用中如何选择使用何种排序
———————————————————————————————————————————————————————————————————————
算法 是否稳定 是否为原地排序 N个元素排序的复杂度 备注 适用场景
时间复杂度 空间复杂度
———————————————————————————————————————————————————————————————————————
选择排序 否 是 N*N 1 适合小规模数组
插入排序 是 是 介于N和N*N之间 1 取决于输入元素的排列情况 适合插入排序对部分有序的数组十分高效,也很适合小规模数组
希尔排序 否 是 NlogN? 1 适合大规模乱序数组
快速排序 否 是 NlogN lgN 运行效率由概率保证 适用无重复元素的数组排序。运行时间至关重要而稳定性要求不是很高时,快速排序可能是最好的
三向快速排序 否 是 介于N和NlogN之间 lgN 运行效率由概率提供保证,也取决于输入元素的分布情况 适用大量重复元素的数组排序,如企业可能需要将大量人员资料按照生日或性别排序
归并排序 是 否 NlogN N 稳定性很重要而空间不是问题时,归并排序可能是最好的
堆排序 否 是 NlogN 1 插入操作和删除最大元素操作混合的动态场景(此时运行时间能保证是对数级别的)
三.各常用算法耗时比较
见SortCompare.java
Stopwatch.java为耗时类
/******************************************************************************
* Compilation: javac SortCompare.java
* Execution: java SortCompare Insertion Selection 1000 100
* 1000 means the Length of automatically generating arrays
* 100 means repeats times
* Compare the running time of these algorithms.
*
*
* % java SortCompare Insertion Selection 1000 100
* For 1000 random Doubles Insertion takes 0.125 seconds
* For 1000 random Doubles Selection takes 0.125 seconds
*
*
* % java SortCompare Insertion Selection Shell Merge Quick Heap 1000 100
* For 1000 random Doubles Insertion takes 0.094 seconds
* For 1000 random Doubles Selection takes 0.094 seconds
* For 1000 random Doubles Shell takes 0.109 seconds
* For 1000 random Doubles Merge takes 0.062 seconds
* For 1000 random Doubles Quick takes 0.078 seconds
* For 1000 random Doubles Heap takes 0.032 seconds
*
*
* % java SortCompare Insertion Selection Shell Merge Quick Heap 100000 100
* For 100000 random Doubles Insertion takes 1447.799 seconds
* For 100000 random Doubles Selection takes 1217.424 seconds
* For 100000 random Doubles Shell takes 3.613 seconds
* For 100000 random Doubles Merge takes 2.467 seconds
* For 100000 random Doubles Quick takes 1.973 seconds
* For 100000 random Doubles Heap takes 2.812 seconds
*
******************************************************************************/ import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
public class SortCompare
{
private static final String[] ALG = {"Insertion", "Selection", "Shell", "Merge", "Quick", "Heap"}; /**
* time
* @param alg algorithm name
* @param a the array
*/
public static double time(String alg, Double[] a){
Stopwatch timer = new Stopwatch(); // printBeforeSort(alg, a); // Print the original array if(alg.equals("Insertion")){
Insertion.sort(a);
} else if(alg.equals("Selection")){
Selection.sort(a);
} else if(alg.equals("Shell")){
Shell.sort(a);
} else if(alg.equals("Merge")){
Merge.sort(a);
} else if(alg.equals("Quick")){
Quick.sort(a);
} else if(alg.equals("Heap")){
Heap.sort(a);
} // printAfterSort(alg, a); // Print the sorted array return timer.elapsedTime();
} /**
* total elapsed time
* @param alg algorithm name
* @param N the length of the array
* @param T repeats times
*/
public static double timeRandomInput(String alg, int N, int T)
{
// Sort T arrays of length N by using algorithm
double total = 0.0;
Double[] a = new Double[N];
for(int t = 0; t < T; t++)
{
// generate and sort
for(int i = 0; i < N; i++)
{
a[i] = StdRandom.uniform();
}
total += time(alg, a);
}
return total;
} public static void main(String[] args)
{
testDataFromArgs(args); //testDataFromFile(args);
} /**
*
* % java SortCompare Insertion Selection 1000 100
*/
private static void testDataFromArgs(String[] args){
if(args == null || args.length < 3){
System.out.println("Incorrect number of arguments,the mininum mumber is 3!!!");
return;
} int len = args.length -2;
List<String> al = new ArrayList<String>(Arrays.asList(ALG));
for(int i = 0; i < len;i++){
if(!al.contains(args[i]))
{
System.out.println("Contains unknown algorithm names!!!");
return;
}
} int N = Integer.parseInt(args[len]);
int T = Integer.parseInt(args[len + 1]); double t = 0.0;
for(int i = 0; i < len;i++){
t = timeRandomInput(args[i], N, T);// total time of algorithm
System.out.format("For %d random Doubles %s takes %.3f seconds \n", N, args[i], t);
}
} /**
*
* % more test.txt
*
* % java SortCompare < test.txt
*/
private static void testDataFromFile(String[] args){
double[] b = StdIn.readAllDoubles();
int N = b.length;
int T = 100;
Double[] a = new Double[N]; for(int i = 0;i < N;i++){
a[i] = b[i];
} int len = ALG.length;
double t = 0.0;
for(int i = 0; i < len;i++){
t = timeRandomInput(ALG[i], a, T);// total time of algorithm
System.out.format("For %d random Doubles %s takes %.3f seconds \n", N, ALG[i], t);
}
} private static double timeRandomInput(String alg, Double[] a, int T)
{
// Sort T arrays of length N by using algorithm
double total = 0.0;
for(int t = 0; t < T; t++)
{
total += time(alg, a);
}
return total;
} private static void printBeforeSort(String alg, Double[] a){
if(a.length > 50){
return;
}
System.out.format("\n%s --- before sort\n", alg);
show(a);
} private static void printAfterSort(String alg, Double[] a){
if(a.length > 50){
return;
}
System.out.format("\n%s --- after sort\n", alg);
show(a);
} private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
}
Stopwatch.java源码如下:
* Initializes a new stopwatch.
*/
public Stopwatch() {
start = System.currentTimeMillis();
}
* Returns the elapsed CPU time (in seconds) since the stopwatch was created.
*
* @return elapsed CPU time (in seconds) since the stopwatch was created
*/
public double elapsedTime() {
long now = System.currentTimeMillis();
return (now - start) / 1000.0;
}
/**
* Unit tests the {@code Stopwatch} data type.
* Takes a command-line argument {@code n} and computes the
* sum of the square roots of the first {@code n} positive integers,
* first using {@code Math.sqrt()}, then using {@code Math.pow()}.
* It prints to standard output the sum and the amount of time to
* compute the sum. Note that the discrete sum can be approximated by
* an integral - the sum should be approximately 2/3 * (n^(3/2) - 1).
*
* @param args the command-line arguments
*/
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
Stopwatch timer1 = new Stopwatch();
double sum1 = 0.0;
for (int i = 1; i <= n; i++) {
sum1 += Math.sqrt(i);
}
double time1 = timer1.elapsedTime();
System.out.format("%e (%.2f seconds)\n", sum1, time1);
// sum of square roots of integers from 1 to n using Math.pow(x, 0.5).
Stopwatch timer2 = new Stopwatch();
double sum2 = 0.0;
for (int i = 1; i <= n; i++) {
sum2 += Math.pow(i, 0.5);
}
double time2 = timer2.elapsedTime();
System.out.format("%e (%.2f seconds)\n", sum2, time2);
}
}
常用算法之排序(Java)的更多相关文章
- 面试常用算法总结——排序算法(java版)
排序算法 重要性不言而喻,很多算法问题往往选择一个好的排序算法往往问题可以迎刃而解 1.冒泡算法 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个 ...
- 基本排序算法——shell排序java实现
shell排序是对插入排序的一种改进. package basic.sort; import java.util.Arrays; import java.util.Random; public cla ...
- 基本排序算法——选择排序java实现
选择排序与冒泡排序有很大的相同点,都是一次遍历结束后能确定一个元素的最终位置,其主要思路是,一次遍历选取最小的元素与第一个元素交换,从而使得一个个元素有序,而后选择第二小的元素与第二个元素交换,知道, ...
- 八大排序算法总结与java实现(转)
八大排序算法总结与Java实现 原文链接: 八大排序算法总结与java实现 - iTimeTraveler 概述 直接插入排序 希尔排序 简单选择排序 堆排序 冒泡排序 快速排序 归并排序 基数排序 ...
- 【Java】-NO.13.Algorithm.1.Java Algorithm.1.001-【Java 常用算法手册 】-
1.0.0 Summary Tittle:[Java]-NO.13.Algorithm.1.Java Algorithm.1.001-[Java 常用算法手册 ]- Style:Java Series ...
- 排序算法总结(基于Java实现)
前言 下面会讲到一些简单的排序算法(均基于java实现),并给出实现和效率分析. 使用的基类如下: 注意:抽象函数应为public的,我就不改代码了 public abstract class Sor ...
- 常见排序算法题(java版)
常见排序算法题(java版) //插入排序: package org.rut.util.algorithm.support; import org.rut.util.algorithm.Sor ...
- 第二章:排序算法 及其他 Java代码实现
目录 第二章:排序算法 及其他 Java代码实现 插入排序 归并排序 选择排序算法 冒泡排序 查找算法 习题 2.3.7 第二章:排序算法 及其他 Java代码实现 --算法导论(Introducti ...
- Java实现 蓝桥杯 算法训练 排序
算法训练 排序 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,输入3个整数,然后程序将对这三个整数按照从大到小进行排列. 输入格式:输入只有一行,即三个整数,中间用空格隔开. ...
随机推荐
- 使用 evo 工具评测 VI ORB SLAM2 在 EuRoC 上的结果
http://www.liuxiao.org/2017/11/%E4%BD%BF%E7%94%A8-evo-%E5%B7%A5%E5%85%B7%E8%AF%84%E6%B5%8B-vi-orb-sl ...
- Spring cloud微服务安全实战-3-8API安全机制之Https
Https访问 1.验证双方的身份. 2.一旦建立连接,对数据进行封装加密 这里先生成一个自己自签的证书,不是第三方颁发的,第三方颁发的要花钱. 第二是做一些配置,让程序支持https 安装了java ...
- RabbitMQ 入门教程(PHP版) 延迟队列,延迟任务
延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...
- Python初级 2 记住内存和变量的练习
一.数据类型: 数字:3, 5, 100, 50.35 字符串:"abc","wang" 字符串或数字可以由名字来表示,名字也叫变量 二.算术表达式: 形如3 ...
- python flask框架学习(一)——准备工作和环境配置与安装
Flask装备: 学习自:知了课堂Python Flask框架——全栈开发 1.Python版本:3.6 2.Pycharm软件: 3.安装虚拟环境: (1)安装virtualenv: pip ins ...
- Spring Boot与ActiveMQ的集成
Spring Boot对JMS(Java Message Service,Java消息服务)也提供了自动配置的支持,其主要支持的JMS实现有ActiveMQ.Artemis等.本节中,将以Active ...
- spring 加载属性(properties)文件
在开发的过程中,配置文件往往就是那些属性(properties)文件,比如使用properties文件配置数据库文件,又如database-config.properties 代码清单:databas ...
- LeetCode_283. Move Zeroes
283. Move Zeroes Easy Given an array nums, write a function to move all 0's to the end of it while m ...
- git 打tag(版本)、推送代码
服务端:192.168.0.96 gitlab 客户端:192.168.0.97 git 服务端gitlab安装请参照: https://www.cnblogs.com/effortsing/p/10 ...
- LintCode: coins in a line I
有 n 个硬币排成一条线.两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是输还是赢? n = 1, 返回 true.n = 2, ...