网站建设柒金手指排名二一/东莞做一个企业网站
排序算法 —— 希尔排序
算法介绍
希尔排序(Shell Sort)是一种基于插入排序的算法,由Donald Shell于1959年提出。希尔排序的基本思想是将待排序的序列划分成若干个子序列,分别进行插入排序,待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序。
算法基本思想
基本概念
- 间隔序列:希尔排序中,间隔序列是一个递减的序列,用于控制子序列的划分。初始间隔较大,逐步减小,最终减至1,此时整个序列被视为一个子序列。
- 子序列:根据间隔序列,将原始序列划分成若干个子序列,每个子序列中的元素间隔为当前间隔序列中的数值。
算法步骤
- 选择一个间隔序列 ( G_1, G_2, …, G_t ),其中 ( G_t = 1 )。
- 根据当前间隔 ( G_i ),将序列分成若干子序列,对每个子序列进行插入排序。
- 减小间隔 ( G_{i+1} ),重复步骤2,直至间隔为1,此时整个序列被视为一个子序列,进行最后一次插入排序。
伪代码描述
function shellSort(arr):n = length(arr)gap = n / 2while gap > 0:for i = gap; i < n; i++:temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempgap = gap / 2return arr
优点
- 效率提升:希尔排序比传统的插入排序在效率上有显著提升,特别是当数据量较大时。
- 减少移动次数:通过比较距离较远的元素,希尔排序减少了元素之间的比较和移动次数,从而提高了排序效率。
- 灵活性:希尔排序的间隔序列可以灵活选择,不同的间隔序列可能会带来不同的性能表现。
- 易于实现:希尔排序的算法实现相对简单,理解和实现起来比较容易。
缺点
- 时间复杂度:在最坏的情况下,希尔排序的时间复杂度仍然是 (O(n^2)),这使得它在处理大数据集时可能不如其他更高效的排序算法(如快速排序、归并排序等)。
- 不稳定排序算法:希尔排序不是稳定的排序算法,相同值的元素可能会因为间隔序列的选择而交换位置。
- 依赖间隔序列:希尔排序的性能很大程度上取决于间隔序列的选择,选择不当可能会导致性能不如插入排序。
应用场景
- 小规模数据:对于小规模的数据集,希尔排序可能比其他算法更快,因为其时间复杂度接近线性。
- 简单应用:在不需要高精度或稳定性,且数据规模不大的情况下,希尔排序是一个不错的选择。
- 教育与学习:由于其算法实现简单,希尔排序常被用于教学,帮助初学者理解排序算法的概念。
尽管希尔排序在理论上的时间复杂度不如一些现代排序算法,但在实际应用中,尤其是在数据量不是非常大时,希尔排序由于其低廉的实现成本和较好的性能,仍然是一个可行的选择。此外,对于一些特定数据结构和数据集,通过精心设计的间隔序列,希尔排序可以展现出比传统插入排序更好的性能。
时间复杂度
希尔排序的时间复杂度分析相对复杂,因为它依赖于间隔序列的选择。以下是几种不同情况下的时间复杂度分析
最坏情况
在最坏的情况下,希尔排序的时间复杂度为 (O(n^2))。这是因为在最坏情况下,每次插入排序操作都需要移动其他元素。由于希尔排序是通过比较间隔序列中的元素来进行的,因此存在一种情况,其中间隔序列被设置为非常小的值(例如1),这实际上将希尔排序转换为普通的插入排序。
平均情况
在平均情况下,希尔排序的时间复杂度通常被认为介于 (O(n^{1.3} \log n)) 到 (O(n^{2.25} \log n)) 之间。这是因为在平均情况下,插入排序的效率得到了提高,因为每次插入操作不需要移动所有的元素。
最佳情况
在最佳情况下,希尔排序的时间复杂度可以达到 (O(n \log^2 n))。这是当间隔序列被设计得非常好的情况下,例如使用Sedgewick间隔序列时。在这种情况下,每次插入操作需要移动的元素数量较少,因此整体效率较高。
空间复杂度
希尔排序的空间复杂度为 (O(1))。这是因为希尔排序是原地排序算法,除了输入数组本身之外,它只需要一个很小的常数空间来存储间隔序列和临时变量。因此,希尔排序不需要额外的内存空间来完成排序。
证明
由于希尔排序的时间复杂度分析依赖于间隔序列的选择,没有统一的数学证明来确定其时间复杂度。上述的时间复杂度是基于实验和观察得出的,而不是精确的数学证明。然而,对于特定的间隔序列,如Sedgewick间隔序列,已经有一些研究表明它在平均和最佳情况下的时间复杂度。
总的来说,希尔排序的时间复杂度分析是实验性的,而不是理论性的。在实际应用中,选择合适的间隔序列可以显著提高希尔排序的性能,使其在某些情况下比传统的插入排序更有效率。
代码实现
Python 实现
def shell_sort(arr):n = len(arr)gap = n // 2while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempgap //= 2
C++ 实现
void shellSort(int arr[], int n) {for (int gap = n/2; gap > 0; gap /= 2) {for (int i = gap; i < n; i += 1) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}
C++ 模板实现
template <typename T>
void shellSort(vector<T> &arr)
{// n is the size of the arrayint n = arr.size();// gap is the difference between the current position and the gap positionfor (int gap = n / 2; gap > 0; gap /= 2){// i is the current positionfor (int i = gap; i < n; ++i){// temp is the current elementT temp = arr[i];// j is the gap positionint j;// loop from i to gap and swap the elements if the gap position is greater than the current elementfor (j = i; j >= gap && arr[j - gap] > temp; j -= gap){arr[j] = arr[j - gap];}// swap the current element with the gap positionarr[j] = temp;}}
}
扩展阅读
优化时间复杂度的思路
- 选择合适的间隔序列:选择一个好的间隔序列是优化希尔排序的关键。Sedgewick间隔序列和Poonen间隔序列是经过精心设计的,可以在平均和最佳情况下提供较好的性能。
- 自定义间隔序列:根据具体的数据集特点,可以设计自定义的间隔序列,以适应特定的数据分布,从而提高排序效率。
- 减少比较和移动的次数:通过改进插入排序的实现,减少不必要的比较和元素的移动,可以提高希尔排序的效率。
历史上针对希尔排序时间复杂度的变种算法
- Sedgewick希尔排序:Robert Sedgewick提出了使用特定的间隔序列(Sedgewick间隔序列)来优化希尔排序。这种方法在平均和最佳情况下提供了较好的性能。
- Poonen希尔排序:Larry Poonen提出了使用一组固定的间隔序列来优化希尔排序,这些间隔序列不需要依赖于输入数据的规模。
- Knuth希尔排序:Donald Knuth提出了一种基于斐波那契数列的间隔序列,这种方法在某些情况下也表现良好。
- Hibbard希尔排序:虽然不是专门为时间复杂度优化设计的,但Hibbard间隔序列在某些情况下也可以提供较好的性能。
除了这些基于间隔序列优化的方法,还有一些其他的工作致力于改进希尔排序的性能,例如通过减少比较和交换操作来提高效率。然而,尽管这些方法可能对特定数据集或特定情况有所帮助,但它们并没有产生新的希尔排序变种,而是在原有算法基础上的一些改进。希尔排序的时间复杂度优化主要集中在间隔序列的选择和实现细节的优化上。通过选择合适的间隔序列和优化实现,可以在一定程度上提高希尔排序的性能。然而,需要注意的是,希尔排序的时间复杂度仍然在最坏情况下是 (O(n^2)),这使得它在处理大数据集时可能不如其他更高效的排序算法。
Hibbard希尔排序
伪代码
function hibbardShellSort(arr):n = length(arr)k = 1while (2^k - 1) < n:k += 1for gap = 2^(k-1) - 1; gap > 0; gap = (gap / 2) - 1:for i = gap; i < n; i++:temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempreturn arr
Python代码
def hibbard_shell_sort(arr):n = len(arr)k = 0while (1 << k) - 1 < n:k += 1gaps = [1]for i in range(k):gaps.append((1 << (2 * i)) - 1)for gap in reversed(gaps):for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = temp
C++模板代码
template <typename T>
void hibbardShellSort(vector<T> &arr)
{// Calculate the size of the arrayint n = arr.size();// Calculate the number of levels in the treeint k = 1;// Calculate the number of elements in each level of the treewhile ((1 << k) - 1 < n){k++;}// Sort each level of the treefor (int gap = (1 << (k - 1)) - 1; gap > 0; gap = (gap >> 1) - 1){// Sort each element in the levelfor (int i = gap; i < n; ++i){// Store the current element in a temporary variableT temp = arr[i];// Find the correct position for the elementint j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap){// Move the element to the correct positionarr[j] = arr[j - gap];}// Put the element in its correct positionarr[j] = temp;}}
}
完整的项目代码
Python
def shell_sort(arr):n = len(arr)gap = n // 2while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempgap //= 2def hibbard_shell_sort(arr):n = len(arr)k = 0while (1 << k) - 1 < n:k += 1gaps = [1]for i in range(k):gaps.append((1 << (2 * i)) - 1)for gap in reversed(gaps):for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempdef knuth_shell_sort(arr):n = len(arr)k = 0fib = 1while fib < n:k += 1fib = (k % 2 == 0) and (3 * fib + 1) or (3 * fib - 1)gaps = [(fib - 1) for i in range(k, 0, -1)]for gap in reversed(gaps):for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempdef sedgewick_shell_sort(arr):n = len(arr)gap = 1while gap < n / 3:gap = 3 * gap + 1while gap > 0:for i in range(gap, n):temp = arr[i]j = iwhile j >= gap and arr[j - gap] > temp:arr[j] = arr[j - gap]j -= gaparr[j] = tempgap //= 3class Person:def __init__(self, name, age, score):self.name = nameself.age = ageself.score = scoredef __lt__(self, other):return self.score < other.scoredef __le__(self, other):return self.score <= other.scoredef __eq__(self, other):return self.score == other.score and self.age == other.age and self.name == other.namedef __ne__(self, other):return not self.__eq__(other)def __gt__(self, other):return self.score > other.scoredef __ge__(self, other):return self.score >= other.scoredef get_name(self):return self.namedef get_age(self):return self.agedef get_score(self):return self.scoredef test_shell_sort():data = [9, 8, 3, 7, 5, 6, 4, 1]shell_sort(data)print(data)d_data = [9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1]shell_sort(d_data)print(d_data)c_data = ['a', 'c', 'b', 'd', 'e']shell_sort(c_data)print(c_data)p_data = [Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)]shell_sort(p_data)for person in p_data:print(person.get_name(), person.get_age(), person.get_score())def test_hibbard_shell_sort():data = [9, 8, 3, 7, 5, 6, 4, 1]hibbard_shell_sort(data)print(data)d_data = [9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1]hibbard_shell_sort(d_data)print(d_data)c_data = ['a', 'c', 'b', 'd', 'e']hibbard_shell_sort(c_data)print(c_data)p_data = [Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)]hibbard_shell_sort(p_data)for person in p_data:print(person.get_name(), person.get_age(), person.get_score())def test_knuth_shell_sort():data = [9, 8, 3, 7, 5, 6, 4, 1]knuth_shell_sort(data)print(data)d_data = [9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1]knuth_shell_sort(d_data)print(d_data)c_data = ['a', 'c', 'b', 'd', 'e']knuth_shell_sort(c_data)print(c_data)p_data = [Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)]knuth_shell_sort(p_data)for person in p_data:print(person.get_name(), person.get_age(), person.get_score())def test_sedgewick_shell_sort():data = [9, 8, 3, 7, 5, 6, 4, 1]sedgewick_shell_sort(data)print(data)d_data = [9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1]sedgewick_shell_sort(d_data)print(d_data)c_data = ['a', 'c', 'b', 'd', 'e']sedgewick_shell_sort(c_data)print(c_data)p_data = [Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)]sedgewick_shell_sort(p_data)for person in p_data:print(person.get_name(), person.get_age(), person.get_score())if __name__ == "__main__":test_shell_sort()test_hibbard_shell_sort()test_knuth_shell_sort()test_sedgewick_shell_sort()
C++
#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <string>using namespace std;class Person
{
public:Person(string name, int age, int score){this->name = name;this->age = age;this->socre = score;}// Override the operator> for other function to use.bool operator>(const Person &other) const{// Compare the socre of two Person objects.return this->socre > other.socre;}// Override the operator< for other function to use.bool operator<(const Person &other) const{// Compare the socre of two Person objects.return this->socre < other.socre;}// Override the operator== for other function to use.bool operator==(const Person &other) const{// Compare the socre, age and name of two Person objects.return this->socre == other.socre &&this->age == other.age &&this->name == other.name;}// Override the operator!= for other function to use.bool operator!=(const Person &other) const{// Compare the socre, age and name of two Person objects.return this->socre != other.socre ||this->age != other.age ||this->name != other.name;}// Override the operator<= for other fnction to use.bool operator<=(const Person &other) const{// Compare the socre, age and name of two Person objects.return this->socre <= other.socre &&this->age <= other.age &&this->name <= other.name;}// Override the operator>= for other function to use.bool operator>=(const Person &other) const{// Compare the socre, age and name of two Person objects.return this->socre >= other.socre &&this->age >= other.age &&this->name >= other.name;}// Now there are some get parameters function for this calss:const string &getName() const { return this->name; }int getAge() const { return this->age; }int getScore() const { return this->socre; }private:string name;int age;int socre;
};template <typename T>
void shellSort(vector<T> &arr)
{// n is the size of the arrayint n = arr.size();// gap is the difference between the current position and the gap positionfor (int gap = n / 2; gap > 0; gap /= 2){// i is the current positionfor (int i = gap; i < n; ++i){// temp is the current elementT temp = arr[i];// j is the gap positionint j;// loop from i to gap and swap the elements if the gap position is greater than the current elementfor (j = i; j >= gap && arr[j - gap] > temp; j -= gap){arr[j] = arr[j - gap];}// swap the current element with the gap positionarr[j] = temp;}}
}void shellSortTestCase()
{vector<int> data = {9, 8, 3, 7, 5, 6, 4, 1};shellSort<int>(data);for (int i : data){cout << i << " ";}cout << endl;vector<double> dData = {9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1};shellSort<double>(dData);for (double i : dData){cout << i << " ";}cout << endl;vector<char> cData = {'a', 'c', 'b', 'd', 'e'};shellSort<char>(cData);for (char i : cData){cout << i << " ";}cout << endl;vector<Person> pData = {Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)};shellSort<Person>(pData);for (Person i : pData){cout << i.getName() << " " << i.getAge() << " " << i.getScore() << endl;}cout << endl;
}template <typename T>
void hibbardShellSort(vector<T> &arr)
{// Calculate the size of the arrayint n = arr.size();// Calculate the number of levels in the treeint k = 1;// Calculate the number of elements in each level of the treewhile ((1 << k) - 1 < n){k++;}// Sort each level of the treefor (int gap = (1 << (k - 1)) - 1; gap > 0; gap = (gap >> 1) - 1){// Sort each element in the levelfor (int i = gap; i < n; ++i){// Store the current element in a temporary variableT temp = arr[i];// Find the correct position for the elementint j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap){// Move the element to the correct positionarr[j] = arr[j - gap];}// Put the element in its correct positionarr[j] = temp;}}
}void hibbardShellSortTestCase()
{vector<int> data = {9, 8, 3, 7, 5, 6, 4, 1};hibbardShellSort<int>(data);for (int i : data){cout << i << " ";}cout << endl;vector<double> dData = {9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1};hibbardShellSort<double>(dData);for (double i : dData){cout << i << " ";}cout << endl;vector<char> cData = {'a', 'c', 'b', 'd', 'e'};hibbardShellSort<char>(cData);for (char i : cData){cout << i << " ";}cout << endl;vector<Person> pData = {Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)};hibbardShellSort<Person>(pData);for (Person i : pData){cout << i.getName() << " " << i.getAge() << " " << i.getScore() << endl;}cout << endl;
}template <typename T>
void knuthShellSort(vector<T> &arr)
{// find the length of the arrayint n = arr.size();// initialize the gapint k = 0;// initialize the fibonacci numberlong long fib = 1;// calculate the fibonacci numberwhile (fib < n){k++;fib = (k % 2 == 0) ? (3 * fib + 1) : (3 * fib - 1);}// create a vector to store the gapsvector<int> gaps;// calculate the gapsfor (int i = k; i >= 0; i--){fib = (i % 2 == 0) ? (3 * fib + 1) : (3 * fib - 1);gaps.push_back(static_cast<int>(fib) - 1);}// sort the array using the gapsfor (auto gap = gaps.rbegin(); gap != gaps.rend(); ++gap){// sort the array within the gapfor (int i = *gap; i < n; ++i){T temp = arr[i];int j;// find the correct positionfor (j = i; j >= *gap && arr[j - *gap] > temp; j -= *gap){arr[j] = arr[j - *gap];}arr[j] = temp;}}
}void knuthShellSortTestCase()
{vector<int> data = {9, 8, 3, 7, 5, 6, 4, 1};knuthShellSort<int>(data);for (int i : data){cout << i << " ";}cout << endl;vector<double> dData = {9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1};knuthShellSort<double>(dData);for (double i : dData){cout << i << " ";}cout << endl;vector<char> cData = {'a', 'c', 'b', 'd', 'e'};knuthShellSort<char>(cData);for (char i : cData){cout << i << " ";}cout << endl;vector<Person> pData = {Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)};knuthShellSort<Person>(pData);for (Person i : pData){cout << i.getName() << " " << i.getAge() << " " << i.getScore() << endl;}cout << endl;
}template <typename T>
void sedgewickShellSort(vector<T> &arr)
{int n = arr.size();int i = 0;while ((9 * (1 << (2 * i)) - 9 * (1 << i) + 1) < n){i++;}vector<int> gaps;for (int j = 0; j < i; j++){gaps.push_back(9 * (1 << (2 * j)) - 9 * (1 << j) + 1);}for (auto gap = gaps.rbegin(); gap != gaps.rend(); ++gap){for (int i = *gap; i < n; ++i){T temp = arr[i];int j;for (j = i; j >= *gap && arr[j - *gap] > temp; j -= *gap){arr[j] = arr[j - *gap];}arr[j] = temp;}}
}void sedgewickTestCase()
{vector<int> data = {9, 8, 3, 7, 5, 6, 4, 1};sedgewick<int>(data);for (int i : data){cout << i << " ";}cout << endl;vector<double> dData = {9.9, 9.1, 3.3, 7.7, 5.5, 6.6, 4.4, 1.1};sedgewick<double>(dData);for (double i : dData){cout << i << " ";}cout << endl;vector<char> cData = {'a', 'c', 'b', 'd', 'e'};sedgewick<char>(cData);for (char i : cData){cout << i << " ";}cout << endl;vector<Person> pData = {Person("Alice", 20, 90), Person("Bob", 18, 85), Person("Charlie", 22, 95)};sedgewick<Person>(pData);for (Person i : pData){cout << i.getName() << " " << i.getAge() << " " << i.getScore() << endl;}cout << endl;
}int main()
{shellSortTestCase();hibbardShellSortTestCase();knuthShellSortTestCase();sedgewickTestCase();return 0;
}
相关文章:

[算法沉淀记录] 排序算法 —— 希尔排序
排序算法 —— 希尔排序 算法介绍 希尔排序(Shell Sort)是一种基于插入排序的算法,由Donald Shell于1959年提出。希尔排序的基本思想是将待排序的序列划分成若干个子序列,分别进行插入排序,待整个序列中的记录基本有…...

conda 进入虚拟环境命令报错
问题描述 conda-script.py: error: argument COMMAND: invalid choice: activate 解决方案: 在终端命令先执行 conda init,重置conda环境。然后退出终端,重新进入终端即可conda activate env了。...

域名 SSL 证书信息解析 API 数据接口
域名 SSL 证书信息解析 API 数据接口 网络工具,提供域名 SSL 证书信息解析,多信息查询,毫秒级响应。 1. 产品功能 提供域名 SSL 证书信息解析;最完整 SSL 属性信息解析;支持多种元素信息抽取,包括主题的可…...

学习JAVA的第二天(基础)
目录 基本概念 关键字 class关键字 字面量 练习 变量 定义格式 变量使用 数据类型 基本数据类型 标识符 命名规则 键盘录入 1.导包 2.创建对象 3.接受数据 运算符 算术运算符 练习 隐式转换(自动类型提升) 强制转换 自增自减运算符 …...

代码随想录算法训练营第二十七天|93.复原IP地址、78.子集、90.子集II
93.复原IP地址 刷题https://leetcode.cn/problems/restore-ip-addresses/description/文章讲解https://programmercarl.com/0093.%E5%A4%8D%E5%8E%9FIP%E5%9C%B0%E5%9D%80.html视频讲解https://www.bilibili.com/video/BV1XP4y1U73i/?vd_sourceaf4853e80f89e28094a5fe1e220d9…...

【蓝桥备赛】字串简写
字串简写 数据范围 字符串的长度为5*10的五次方,on方时间复杂度会很大。 才用动态规划的思想,dp[i]以i开头的的可能性,因为长度必须大于等于k,当i小于k的时候,如果等于第一个字符,s1时,dp[…...

nios ii开发随笔
错误一: d:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_64-mingw32/bin/../lib/gcc/nios2-elf/5.3.0/../../../../../H-x86_64-mingw32/nios2-elf/bin/ld.exe: test.elf section .text will not fit in region ram_oc_xzs d:/intelfpga/17.1/nios2eds/bin/gnu/h-x86_6…...

SpringBoot项目嵌入RabbitMQ
在Spring Boot中嵌入RabbitMQ可以通过添加相应的依赖来完成。首先需要在pom.xml文件中引入spring-boot-starter-amqp依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</a…...

提升网络质量:UDPspeeder 实现网络优化与提速
提升网络质量:UDPspeeder 实现网络优化与提速 背景与意义原理与功能使用方法未来展望相关链接服务 在当今高度互联的网络环境下,网络质量的优化和提速对于用户体验至关重要。针对高延迟和丢包率较高的网络链路,UDPspeeder 提供了一种前向纠错…...

为什么前端开发变得越来越复杂了?这可能是我们的错
前端训练营:1v1私教,终身辅导计划,帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer。欢迎来撩~~~~~~~~ Hello,大家好,我是 Sunday。 最近有很多同学来问我:“Sunday 老师,前端学起…...

VR系统的开发流程
虚拟现实(Virtual Reality,VR)系统是一种通过计算机技术模拟出的具有三维视角和交互性的虚拟环境,使用户能够沉浸在其中并与虚拟环境进行交互。这种技术通常利用头戴式显示器和手柄等设备,使用户能够感觉到仿佛身临其境…...

前端输入框校验限制不能输入中文
一般我们在做表单的时候都会有表单校验,通常都是用element提供的表单验证的功能,只需要通过 rules 属性传入约定的验证规则,如下面这样 rules: {userName: [{validator: checkUsername,trigger: "blur",},{ validator: this.checkData, trigge…...

强大的文本绘图——PlantUML
PlantUML是一款开源工具,它允许用户通过简单的文本描述来创建UML图(统一建模语言图)。这种方法可以快速地绘制类图、用例图、序列图、状态图、活动图、组件图和部署图等UML图表。PlantUML使用一种领域特定语言(DSL)&am…...

ES相关问题
在Elasticsearch(ES)集群中,节点根据其配置和角色可以分为以下几种主要类型: Master Node(主节点): 主节点负责管理整个集群的元数据,如索引的创建、删除、分片分配等。它维护着集群…...

基于Linux直接安装的Nginx版本升级方法
引言 随着版本的迭代和漏洞的发现,Nginx作为一款软件避免不了打补丁的命运。 以下基于Linux直接安装的Nginx版本升级。 以下操作均在本地虚拟机中操作验证,请验证后再线上操作。基于centos7测试。 前置资源 获取nginx的最新源码版本网址:…...

探索设计模式的魅力:状态模式揭秘-如何优雅地处理复杂状态转换
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,并且坚持默默的做事。 探索设计模式的魅力:状态模式揭秘-如何优雅地处理复杂状态转换 文章目录 一、案例…...

力扣hot100题解(python版10-12题)
哎- -最近本来就没时间写算法 这算法怎么还这么难。。。 10、和为 K 的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1: 输入:nums [1,1,1]…...

【算法】复杂度分析
第一章、如何分析代码的执行效率和资源消耗 我们知道,数据结构和算法解决的是“快”和“省”的问题,也就是如何让代码运行得更快,一级如何让代码更节省计算机的存储空间。因此,执行效率是评价算法好坏的一个非常重要的指标。那么&…...

车载电子测试学习内容
搜集了一些车载测试的学习内容,大家可以参考。...

STM32F103x 的时钟源
AHB (Advanced High-performance Bus) 高速总线,用来接高速外设的。 APB (Advanced Peripheral Bus) 低速总线,用来接低速外设的,包含APB1 和 APB2。 APB1:上面连接的是低速外设,包括电源接口、备份接口、 CAN 、 US…...

【电路笔记】-RC放电电路
RC放电电路 文章目录 RC放电电路1、概述2、RC放电电路3、RC放电电路示例当电压源从完全充电的 RC 电路中移除时,电容器 C 将通过电阻 R 放电。 1、概述 RC 放电电路利用电阻器-电容器组合的固有 RC 时间常数以指数衰减率对电容器进行放电。 在之前的 RC 充电电路教程中,我们…...

【C++STL】STL容器详解
创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!! 主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步! 🔥c系列专栏:C/C零基础到精通 🔥 给大…...

缓存篇—缓存雪崩
什么是缓存雪崩 通常我们为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并…...

力扣日记2.22-【回溯算法篇】47. 全排列 II
力扣日记:【回溯算法篇】47. 全排列 II 日期:2023.2.22 参考:代码随想录、力扣 47. 全排列 II 题目描述 难度:中等 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: 输…...

如何理解三大微分中值定理
文章看原文,自己写的只是备份 高等数学强化2:一元函数微分学 中值定理 极值点 拐点_一元函数中值定理-CSDN博客 高等数学强化3:一元函数积分学 P积分-CSDN博客 高等数学强化3:定积分几何应用-CSDN博客...

Linux--自定义shell
shell shell就是操作系统提供给用户与操作系统进行交互的命令行界面。它可以理解为一个用户与操作系统之间的接口,用户可以通过输入命令来执行各种操作,如文件管理、进程控制、软件安装等。Shell还可以通过脚本编程实现自动化任务。 常见的Unix系统中使…...

AIGC 实战:Ollama 和 Hugging Face 是什么关系?
Ollama和 Hugging Face 之间存在着双重关系: 1. Ollama是 Hugging Face 开发并托管的工具: Ollama是一个由 Hugging Face 自行开发的开源项目。它主要用于在本地运行大型语言模型 (LLM),特别是存储在 GPT 生成的统一格式 (GPT-Generated Un…...

Gitee教程2(完整流程)
1.配置git git config --global user.name "用户名" git config --global user.email "密码" 如何获取? gitee右上角加号点击新建仓库,仓库名随便起一个就行 找到这条命令,把这两句一个一个复制到vscode终端就行 2.创建g…...

Go 1.22 中的 for 循环新特性详解
目录 每次迭代都创建新变量 支持整数类型循环 小结 在 Go 语言中,for 循环是实现迭代的主要方式。Go 中的 for 循环非常灵活,有多种使用方式,包括传统的三部分 for 循环、类似于其他语言中的 while 循环以及迭代集合的 range 循环。 在 1…...

igolang学习2,golang开发配置国内镜像
go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct...