当前位置: 首页 > wzjs >正文

Wordpress python版上海seo优化外包公司

Wordpress python版,上海seo优化外包公司,做代理去哪个网站找,公司电商网站开发方案排序 1. 排序相关概念 将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序(递增/递减)的序列称为排序 设n个记录的序列为{R1,R2,…,Rn},其相应关键字序列为{K1,K2,…,Kn},这些关键字相互之间可以进行比较…

排序

1. 排序相关概念

将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序(递增/递减)的序列称为排序
设n个记录的序列为{R1,R2,…,Rn},其相应关键字序列为{K1,K2,…,Kn},这些关键字相互之间可以进行比较,即在它们之间存在着一种排序P1,P2,…,Pn,使其相应的关键字满足递增(升序),或递减(降序)的关系。

内排序

  • 在排序过程中,所有排序记录调到内存中进行的排序,整个排序过程不需要访问外存
  • 内排序是排序的基础
  • 内存速度快,比较过程主导性能,内排序效率主要用比较次数和移动次数来衡量

外排序

  • 排序过程中需对外存进行访问的排序
  • 参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成
  • 由于读写延迟是外存性能相关的主要问题,所以,外排序主要用读/写外存的次数作为衡量效率的指标

排序方法的稳定性

  • 稳定的排序方法是若待排序的序列中,存在多个具有相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的

    原始序列:( 5, 3, 7, 2, 8, 10, 4, 7 )
    排序结果:( 2, 3 ,4, 6, 7, 7, 8, 10 ) 是稳定的
    排序结果:( 2, 3 ,4, 6, 7, 7, 8, 10 ) 是不稳定的

2. 插入排序

2.1 直接插入排序

插入排序类似于整理扑克牌。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412092034467.png

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412092035917.png

以下图为例:

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412092024798.gif

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412092041518.png

void InsertSort(int *a, int n)
{for (int i = 1; i < n; i++){int end = i - 1;int temp = a[i];while (end >= 0){if (temp < a[end]){a[end + 1] = a[end];end--;}else{break;}}a[end + 1] = temp;}
}

性能分析如下:

空间复杂度: O ( 1 ) O(1) O(1)

时间复杂度: O ( n 2 ) O(n^2) O(n2)

稳定性:因为每次插入元素时总是从后往前先比较再移动,所以不会出现相同元素相对位置发生变化的情况,即直接插入排序是一个稳定的排序算法。

2.2 折半插入排序

折半插入排序就是使用前面提到的折半查找法,来找到需要插入元素的位置,原理很简单。确定插入位置后,再统一向后挪动元素。

void BInsertSort(SqList &L)
{// 对顺序表L做折半插入排序int i, j, low, high, m;for (i = 2; i <= L.length; ++i){L.r[0] = L.r[i]; // 将待插入的记录暂存到监视哨中low = 1;high = i - 1; // 置查找区间初值while (low <= high)  //折半查找法{                         // 在r[low..high]中折半查找插入的位置m = (low + high) / 2; // 折半if (L.r[0].key < L.r[m].key)high = m - 1; // 插入点在前一子表elselow = m + 1; // 插入点在后一子表} // whilefor (j = i - 1; j >= high + 1; --j)L.r[j + 1] = L.r[j]; // 记录后移L.r[high + 1] = L.r[0];  // 将r[0]即原r[i],插入到正确位置} // for
}

从上述算法中,不难看出折半插入排序仅减少了比较元素的次数,时间复杂度约为 O ( n l o g n ) O(nlogn) O(nlogn)该比较次数与待排序表的初始状态无关,仅取决于表中的元素个数 n n n;而元素的移动次数并未改变它依赖于待排序表的初始状态。因此,折半插入排序的时间复杂度仍为 O ( n 2 ) O(n^2) O(n2),但对于数据量不很大的排序表,折半插入排序往往能表现出很好的性能。折半插入排序是一种稳定的排序算法。折半插入排序仅适用于顺序存储的线性表,比如数组等

2.3 希尔排序

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序

如下图所示,第一趟增量取5,第二趟取增量取3,第三趟增量为1。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101100755.png

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101054695.gif

代码如下:

// 教材写法
void ShellInsert(SqList &L, int dk)
{// 对顺序表L做一趟增量是dk的希尔插入排序int i, j;for (i = dk + 1; i <= L.length; ++i)if (L.r[i].key < L.r[i - dk].key){                    // 需将L.r[i]插入有序增量子表L.r[0] = L.r[i]; // 暂存在L.r[0]for (j = i - dk; j > 0 && L.r[0].key < L.r[j].key; j -= dk)L.r[j + dk] = L.r[j]; // 记录后移,直到找到插入位置L.r[j + dk] = L.r[0];     // 将r[0]即原r[i],插入到正确位置} // for
}
// ShellInsert
void ShellSort(SqList &L, int dt[], int t)
{// 按增量序列dt[0..t-1]对顺序表L作t趟希尔排序int k;for (k = 0; k < t; ++k)ShellInsert(L, dt[k]); // 一趟增量为dt[t]的希尔插入排序
} // ShellSor

我更推荐下面这种写法,直观,便于理解。

template <class T>
void ShellSort(T *a, int n, int gap)
{while (gap > 1){gap = gap / 3 + 1;for (int i = 0; i < n - gap; i++){int end = i;T temp = a[end + gap];while (end >= 0){if (temp < a[end]){a[end + gap] = a[end];end -= gap;}else{break;}}a[end + gap] = temp;}}
}

性能分析如下:

空间复杂度: O ( 1 ) O(1) O(1)

时间复杂度:希尔排序的时间复杂度是尚未解决的难题,没有具体的值,以教材说法为主,主要与gap的值有关。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101108733.png

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101109004.png

稳定性:不稳定,划分不同区间会改变相对次序。

3. 交换排序

3.1 冒泡排序

冒泡排序就不用多说了,典中典,刚开始学习C语言就接触到的排序算法。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101111894.gif

template <class T>
void BubbleSort(T *a, int n)
{for (int i = 0; i < n - 1; i++){bool flag = false;for (int j = 0; j < n - i - 1; j++)//为什么是n-i-1呢,因为第n-i-1个元素是已经排好的{if (a[j] > a[j + 1]){std::swap(a[j], a[j + 1]);flag = true;}}if (!flag)break;}
}
第i趟第i躺排好第几大的值第i趟排好的的第几大的值所在下标
11n-1
22n-2
33n-3
n-1n-11
nn0

相当于就是每次从前往后挪动,都把最大的挪到后面了。以下图为例。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101131565.png

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101131906.png

性能分析如下:

空间复杂度: O ( 1 ) O(1) O(1)

时间复杂度: O ( n 2 ) O(n^2) O(n2)

稳定性:稳定

3.2 快速排序

快速排序算是排序算法中的重点和难点了,希尔排序是插入排序的优化,那么快速排序就是冒泡排序的优化。事实上,不论是C++STL、Java SDK、.NETFrameWorkSDK等开发工具包中的源代码中都能找到它的某种实现版本。

快速排序是一种分治算法,

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101334369.png

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101252890.gif

int PartSort(int *a,int left,int right)
{// 以左边为基准,要先走右找小,再走左找大int key=left;while(left<right){while(left<right&&a[right]>=a[key]){right--;}while(left<right&&a[left]<=a[key]){left++;}std::swap(a[left],a[right]);}std::swap(a[left],a[key]);return left;
}
// 排序范围[left,right)
void QuickSort(int *a,int left,int right)
{if(left>=right)return ;int key=PartSort(a,left,right);QuickSort(a,left,key-1);QuickSort(a,key+1,right);
}
int PartSort(int *a,int left,int right)
{// 以左边为基准,要先走左找大,再走右找小int key=right;while(left<right){while(left<right&&a[left]<=a[key]){left++;}while(left<right&&a[right]>=a[key]){right--;}std::swap(a[left],a[right]);}std::swap(a[left],a[key]);return left;
}
// 排序范围[left,right)
void QuickSort(int *a,int left,int right)
{if(left>=right)return ;int key=PartSort(a,left,right);QuickSort(a,left,key-1);QuickSort(a,key+1,right);
}

性能分析如下:

空间复杂度:由于利用了递归,需要使用栈,最好情况下为 O ( l o g 2 n ) O(log_2n) O(log2n),最坏情况下为 O ( n ) O(n) O(n),平均情况下为

时间复杂度:快速排序是一种高效的排序算法,其核心思想基于分治法。在最理想的情况下,即每次划分都能将数组分为两个几乎相等的子序列时,快速排序的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101623758.png

然而,在最坏的情况下,对逆序和有序的序列使用快速排序,即每次选择的pivot(基准值)都是最大或最小元素,导致每次只能排除一个元素,剩下的元素还需要继续排序,这样会形成类似冒泡排序的情况,需要进行大约n次的划分,每次划分需要遍历几乎所有元素,因此时间复杂度退化为 O ( n 2 ) O(n^2) O(n2)

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101629267.png

稳定性:在划分算法中,若右端区间有两个关键字相同,且均小于基准值的记录,则在交换到左端区间后,它们的相对位置会发生变化,即快速排序是一种不稳定的排序算法。例如,表L={3,2,2},经过一趟排序后L={2,2,3},最终排序序列也是L={2,2.3},显然,2与2的相对次序已发生了变化。

适用性:仅使用与顺序存储的线性表

快速排序可以进行优化,如三数取中。

template <class T>
int minIndex(T *a, int left, int right) // 快速排序三数取中优化法
{int mid = (left + right) / 2;if (a[left] < a[right]){if (a[mid] < a[left]){return left;}else if (a[mid] > a[right]){return right;}else{return mid;}}else{if (a[mid] > a[left]){return left;}else if (a[mid] < a[right]){return right;}else{return mid;}}
}

4. 选择排序

4.1 简单选择排序

简单选择排序就是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的 数据元素排完 。原理简单,不过多说了。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101632244.gif

void SelectSort(int *a, int n)
{for(int i=0;i<n;i++){int minIndex=i;for(int j=i;j<n;j++){if(a[minIndex]>a[j]){minIndex=j;}}if(minIndex!=i)std::swap(a[minIndex],a[i]);}
}

性能分析如下:

空间复杂度: O ( 1 ) O(1) O(1)

时间复杂度: O ( n 2 ) O(n^2) O(n2)

稳定性:在第i趟找到最小元素后,和第i个元素交换,可能会导致第i个元素与含有相同关键字的元素的相对位置发生改变。例如,表L={2,2,1},经过一趟排序后L={1,2,2},最终排序序列也是L={1,2.2},显然,2与2的相对次序已发生变化。因此,简单选择排序是一种不稳定的排序算法。

4.2 堆排序

堆排序就是使用堆这种数据结构来进行排序,注意一点,排升序建大堆,排降序建小堆。

每次建完堆后,将堆顶元素与最后一个元素交换,堆顶元素是最大值,然后在此重新向下调整建堆,要注意建堆的范围。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101654073.png

template <class T>
void AdjustDown(T *a, int parent, int n)
{int child = 2 * parent + 1;while (child < n){if (child + 1 < n && a[child + 1] < a[child])child++;if (a[child] < a[parent]) // 小则交换,构建小根堆{std::swap(a[child], a[parent]);parent = child;child = 2 * parent + 1;}else{ // 没有交换则不需要交换break;}}
}template <class T>
void HeapSort(T *a, int n)
{for (int i = n - 1 - 1 / 2; i >= 0; i--)AdjustDown(a, i, n);for (int i = n - 1; i > 0; i--){std::swap(a[0], a[i]);AdjustDown(a, 0, i);}
}

性能分析如下:

空间复杂度: O ( 1 ) O(1) O(1)

时间复杂度:向下调整建堆的时间复杂度为 O ( n ) O(n) O(n),证明过程见树那一章节,每次调整的时间复杂度为 O ( h ) O(h) O(h),故综合时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

稳定性:堆排序可能把有相同关键字元素排到前面,故堆排序不稳定

5. 归并排序、基数排序、计数排序

5.1 归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:

  1. 把原始需要排序的序列分成两个或多个子序列
  2. 把每个子序列排好序
  3. 把多个排好序的子序列合并称一个序列,即为结果

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101749130.png

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101737437.gif

void _Merge(int *a, int left, int right, int *tmp)
{if (left >= right)return;int mid = (left) + (right - left) / 2;_Merge(a, left, mid, tmp);_Merge(a, mid + 1, right, tmp);int begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;int i = left;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2])tmp[i++] = a[begin1++];elsetmp[i++] = a[begin2++];}//当遍历完其中一个区间,将另一个区间剩余的数据直接放到tmp的后面while (begin1 <= end1)tmp[i++] = a[begin1++];while (begin2 <= end2)tmp[i++] = a[begin2++];// int j=0;for (int j = left; j <= right; j++)a[j] = tmp[j];
}
void MergeSort(int *a, int n)
{int *tmp = (int *)malloc(sizeof(int) * n);_Merge(a, 0, n - 1, tmp);free(tmp);
}

5.2 基数排序

对于数字型或字符型的单关键字,可以看成是由多个数位或多个字符构成的多关键字,采用多关键字排序,称作基数排序。

为实现多关键字排序,通常有两种方法:第一种是最高位优先(MSD)法,按关键字位权重递减依次逐层划分成若干更小的子序列,最后将所有子序列依次连接成一个有序序列;第二种是最低位优先(LSD)法,按关键字位权重递增依次进行排序,最后形成一个有序序列。

https://cdn.jsdelivr.net/gh/junmoxiao6661/pigo_image@main/202412101900254.gif

我们以研究生成绩排序为例,按照分数高低排序,分数相同按专业课排序。

#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#include <iomanip>
#include <ctime>
#include "LinkQueue.hpp"  //自己在实验2写的链栈// 基数排序
#define K 3 // 关键字个数 百位、十位、个位
#define Radix 10struct Student
{int stuid;        // 考生号std::string name; // 姓名int totalScore;   // 总成绩int majorScore;   // 专业课Student() {}// 比较思路如下:// 进行两次分发回收,第一次以专业课,这样的话总分排序时,专业课高的一定在前面Student(int id, const std::string n, int t, int m) : stuid(id), name(n), totalScore(t), majorScore(m){}
};LinkQueue<Student> Q[Radix];
// 基数排序的实现
// 即使用队列将每一次分发的进行存储,每一次分发按照高位到低位进行
int GetKey(int value, int k)
{int key = 0;while (k >= 0){key = value % 10;value /= 10;k--;}return key;
}
void DistributeMajor(std::vector<Student> &a, int left, int right, int k)
{for (int i = left; i < right; i++){int key = GetKey(a[i].majorScore, k);Q[key].push(a[i]);}
}
void DistributeTotal(std::vector<Student> &a, int left, int right, int k)
{for (int i = left; i < right; i++){int key = GetKey(a[i].totalScore, k);Q[key].push(a[i]);}
}
void Collect(std::vector<Student> &a)
{int k = 0;for (int i = 0; i < Radix; i++){while (!Q[i].empty()){a[k++] = Q[i].front();Q[i].pop();}}
}void RadixSort(std::vector<Student> &a, int left, int right)
{for (int i = 0; i < K; i++){DistributeMajor(a, left, right, i);Collect(a);}for (int i = 0; i < K; i++){DistributeTotal(a, left, right, i);Collect(a);}
}int main()
{std::vector<Student> students = {{20240001, "Brian", 338, 82},{20240002, "Queen", 384, 82},{20240003, "Xiomara", 330, 94},{20240004, "Gwen", 347, 74},{20240005, "Ryan", 347, 75},{20240006, "Holly", 325, 92},{20240007, "Damon", 399, 88},{20240008, "Quinn", 440, 120},{20240009, "Yvette", 306, 94},{20240010, "Steve", 306, 79},{20240011, "Mona", 380, 73}};RadixSort(students, 0, students.size());std::cout<< "考生号      "<< "姓名      "<< "总分   "<< "专业课分数" << std::endl;// 打印学生数据for (int i = students.size() - 1; i >= 0; i--){std::cout << std::left<< std::setw(12) << students[i].stuid<< std::setw(10) << students[i].name<< std::setw(10) << students[i].totalScore<< std::setw(12) << students[i].majorScore << std::endl;}return 0;
}
算法平均时间复杂度最坏时间复杂度额外空间复杂度稳定性说明
简单选择排序O(N2)O(N2)O(1)不稳定
冒泡排序O(N2)O(N2)O(1)稳定
直接插入排序O(N2)O(N2)O(1)稳定
快速排序O(NlogN)O(N2)O(logN)不稳定
归并排序O(NlogN)O(NlogN)O(N)稳定
堆排序O(NlogN)O(NlogN)O(1)不稳定
希尔排序O(Nd)O(N2)O(1)不稳定依赖增量序列d
基数排序O(d(N+rd))O(d(N+rd))O(N+rd)稳定d是趟数;rd是基数
http://www.dtcms.com/wzjs/86451.html

相关文章:

  • 中华建设杂志网站吸引人气的营销方案
  • 优化建站seo门户青岛网站运营
  • 织梦手机网站制作石家庄手机端seo
  • 简述php网站开发流程图久久seo正规吗
  • 武汉企业北京首页关键词优化
  • 哪里有网站制作服务游戏代理平台
  • wordpress怎样建立二级菜单seo百度百科
  • 广州市专注网站建设公司上海seo有哪些公司
  • 网站开发及运营代理协议范本互联网站
  • 网站宣传页baiduseoguide
  • 深圳市哪些公司做网站好违禁网站用什么浏览器
  • java图书管理网站建设微信营销模式有哪些
  • 网站建设的投资必要性提高工作效率的软件
  • 自己买域名可以做网站吗做专业搜索引擎优化
  • ghost wordpress比较武汉seo优化服务
  • 旅游+网站建设推广链接怎么制作
  • 俄罗斯网站开发网络推广
  • 南宁手机平台网站建设百度浏览器手机版
  • 做网投网站好百度网盘优化
  • 网站是用织梦系统做的首页打开超慢网络营销的实现方式
  • 课程网站建设技术seo基础知识培训
  • 大连 建网站重庆seo排名扣费
  • 专业做网站设计公司价格百度客服电话是多少
  • 做外贸什么网站比较好cba目前排行
  • 公司网站空间申请制作网页需要多少钱
  • html怎么做查询网站吗怎么做百度网页推广
  • 网站优化网络推广seo百度问一问付费咨询
  • 单页网站seo优化网络推广网站大全
  • 网络培训内容seo公司关键词
  • 外网专门做钙片的网站福州百度推广排名优化