wordpress多站点开启在北京个人怎么注册公司
wordpress多站点开启,在北京个人怎么注册公司,英语培训网站模板,wordpress网站建设归并排序介绍有时候我们需要把两个有序的序列进行合并从而得到有序的大序列#xff0c;基于这个思想#xff0c;便引出了归并排序#xff0c;其思路就是把一个无序序列拆分成多个有序序列(当序列的元素为1时就是有序序列)#xff0c;然后对所有序列进行合并操作#xff0c…归并排序介绍有时候我们需要把两个有序的序列进行合并从而得到有序的大序列基于这个思想便引出了归并排序其思路就是把一个无序序列拆分成多个有序序列(当序列的元素为1时就是有序序列)然后对所有序列进行合并操作最终得到一整个有序序列。实现typedef int ElementType; void Merge(ElementType A[],ElementType TmpArray[],int Lpos,int Rpos,int RightEnd) { int i,LeftEnd,NumElements,TmpPos; LeftEndRpos-1; TmpPosLpos; NumElementsRightEnd-Lpos1; while (LposLeftEnd RposRightEnd) { if (A[Lpos]A[Rpos]) { TmpArray[TmpPos]A[Lpos]; }else { TmpArray[TmpPos]A[Rpos]; } } while (LposLeftEnd) { TmpArray[TmpPos]A[Lpos]; } while (RposRightEnd) { TmpArray[TmpPos]A[Rpos]; } for (i0;iNumElements;i,RightEnd--) { A[RightEnd]TmpArray[RightEnd]; } } void Msort(ElementType A[],ElementType TmpArray[],int Left,int Right) { int Center; if (LeftRight) { Center(LeftRight)/2; Msort(A,TmpArray,Left,Center); Msort(A,TmpArray,Center1,Right); Merge(A,TmpArray,Left,Center1,Right); } } void MergeSort(ElementType A[],int N) { ElementType *TmpArray; TmpArray (ElementType*)malloc(N*sizeof(ElementType)); if (TmpArray!NULL) { Msort(A,TmpArray,0,N-1); free(TmpArray); }else { printf(Not enough memory for Merge Sort\n); } }算法有两个重要的操作一个是将大序列分成小序列的操作一个是将两个有序序列合并成有序大序列的操作。合并操作的逻辑假设要合并序列A和序列B(都是升序)首先创建一个空间大小为A和B元素数量之和的大小。然后比较A和B最左边的元素较小的放新序列里较大的那个和另一个序列的下一个元素比持续这个过程直到其中一个序列遍历完那就把另一个序列剩下的元素放到新序列里就可以了。递归拆分的逻辑将数组从中间拆成左右两部分再对左右两部分再以中间拆成两部分一直这样拆到小序列只要一个元素然后再对这两个小序列进行合并操作一步一步合并直至左右两大部分的序列进行最后一次合并成为最终完成排序的总序列。这里开了一个临时变量TmpArray为了方便后面进行合并操作时频繁新辟用于存两个序列的新数组。分析归并操作包括拆分和合并将数组拆分成许多小数组的的过程一共要进行LogN次每一层的合并最坏要比较N次所以总的时间复杂度为O(LogN)。归并排序是稳定排序因为每一次的拆分都是相邻序列的拆分合并时若两元素相等也是先将左数组的元素放入临时数组这不改变相同元素的相对位置。快速排序介绍当得到一个无序数组那我们随机选其中一个元素然后让剩下的元素中小于它的排在它左边大于它的元素排在它右边这样我们就让这个元素归位了它所在的位置不会在变了。接着再对剩下的元素重复进行这样的操作这样随着一个个元素的归位序也就排好了。实现typedef int ElementType; #define Cutoff (3) void Swap(ElementType *a,ElementType *b) { ElementType Tmp*a; *a*b; *bTmp; } void InsertionSort(ElementType A[],int N) { int j,P; ElementType Tmp; for (P1;PN;P) { TmpA[P]; for (jP;j0A[j-1]Tmp;j--) { A[j]A[j-1]; } A[j]Tmp; } } ElementType Median3(ElementType A[],int Left,int Right) { int Center (LeftRight)/2; if (A[Left]A[Center]) { Swap(A[Left],A[Center]); } if (A[Left]A[Right]) { Swap(A[Left],A[Right]); } if (A[Center]A[Right]) { Swap(A[Center],A[Right]); } Swap(A[Center],A[Right-1]); return A[Right-1]; } void Qsort(ElementType A[],int Left,int Right) { int i,j; ElementType Pivot; if (LeftCutoffRight) { PivotMedian3(A,Left,Right); iLeft; jRight-1; for (;;) { while (A[i]Pivot) {} while (A[--j]Pivot) {} if (ij) { Swap(A[i],A[j]); }else { break; } } Swap(A[i],A[Right-1]); Qsort(A,Left,i-1); Qsort(A,i1,Right); }else { InsertionSort(ALeft,Right-Left1); } } void QuickSort(ElementType A[],int N) { Qsort(A,0,N-1); }这里的排序操作比较灵活算法步骤如下为了提高算法效率防止出现快速排序最坏的情况(避免选到极值做枢轴)先找到待排序数组的左端点中点和右端点这三个位置然后对这三个位置进行排序排好序后将中点的元素和Right-1处的元素进行交换并且将其作为枢轴(枢轴的左边所有元素小于枢轴本身枢轴的右边所有元素大于枢轴本身)。快速排序的核心操作(此操作没有新辟一块空间来存储经交换后快速排序的数组所以空间复杂度较低)使用双指针ij分别从数组最左端和Right-2两次开始遍历先i右移直到找比枢轴大的元素后再j左移直到找到比枢轴小的元素这样如果顺利的话会出现i位置的元素小于j位置的元素那就交换这两个元素然后ij指针接着移动重复上面的操作若出现i的元素大于等于j位置的元素说明ij指针已经不在正确的左右区间了即此时i的位置的元素是第一个大于枢轴的元素的位置那就将枢轴和i位置进行交换这样枢轴的左侧全是小于它的元素枢轴右侧都是大于它的元素。接着再对枢轴左侧的子数组(left到i-1)和右侧数组(i1到Right)递归地进行快速排序的核心操作直到某个小数组的长度小于3数组长度太小用快速排序还是太烦琐了使用就对数组长度小于3的小序列进行插入排序。这样就逐步完成了整个序列的排序分析和归并排序一样选数组的操作及递归层数为LogN每一层最坏要遍历N个元素所以快速排序的时间复杂度是O(NLogN)。快速排序是不稳定排序双指交换元素时可能会打乱相同元素的相对位置。