营销企业网站制作wordpress登陆页面更改
news/
2025/9/22 23:40:22/
文章来源:
营销企业网站制作,wordpress登陆页面更改,上海黑马网站制作,在5分钟内注册小程序排序类型小结 #x1f4a6; 插入排序直接插入排序希尔排序 #x1f4a6; 选择排序直接选择排序堆排序 #x1f4a6; 交换排序冒泡排序快速排序#x1f43e;霍尔版本补坑位版本前后指针版本非递归版本 #x1f4a6; 归并排序递归版本非递归版本 #x1f4a6; 性能测试 插入排序直接插入排序希尔排序 选择排序直接选择排序堆排序 交换排序冒泡排序快速排序霍尔版本补坑位版本前后指针版本非递归版本 归并排序递归版本非递归版本 性能测试 插入排序
直接插入排序 核心思想 把待排序的记录按关键码的大小逐个插入到一个已经排好的序的有序序列中直到所有的记录插入完为止得到一个新的有序序列
❗ 过程❕
当插入第 i(i1) 个元素时前面的 array[0] array[1] … array[i-1] 已经排好序此时用 array[i] 的排序码与 array[i-1] array[i-2]… 的排序码顺序进行比较找到插入位置即将 array[i] 插入原来位置上的元素顺序后移
❗ 直接插入排序的特性总结❕
1️⃣ 元素集合越接近有序直接插入排序算法的时间效率越高
2️⃣ 时间复杂度O(N^2)
3️⃣ 空间复杂度O(1)它是一种稳定的排序算法
4️⃣ 稳定性稳定 代码实现
void InsertSort(int* a, int n)
{//注意这里的n-1for (int i 0; i n-1; i){int end i;int tmp a[end 1];while (end 0){if (tmp a[end]){//后移数组a[end 1] a[end];end--;}else{break;}}a[end 1] tmp;}
}希尔排序
希尔排序 (缩小增量排序) 核心思想
希尔排序法又称缩小增量法。希尔排序法的基本思想是先选定一个整数把待排序文件中所有记录分成若干个组所有距离为 gap 的记录分在同一组内并对每一组内的记录进行排序。然后取重复上述分组和排序的工作。当到达gap 1 时所有记录在统一组内排好序。 希尔排序的时间复杂度并不好计算因为 gap 的取值方法很多导致很难去计算因此在好些数中给出的希尔排序的时间复杂度都不固定官方给出的时间复杂度是 O(N1.3)
以下是其粗略的计算方法可见非常复杂 代码实现
//希尔排序
void ShellSort(int* a, int n)
{int gap n;//gap1时是预排目的是让他接近有序//gap1是直接插入排序目的是让他有序while (gap 1){gap gap / 3 1;//多组并排for (int i 0; i n - gap; i){int end i;int tmp a[end gap];while (end 0){if (tmp a[end]){a[end gap] a[end];end - gap;}elsebreak;}a[end gap] tmp;}}
}❗ 希尔排序特性总结 ❕
1️⃣ 希尔排序是对直接插入排序的优化
2️⃣ 当 gap 1 时都是预排序目的是让数组更接近于有序。当 gap 1 时其实就是直接插入排序且数组已经接近有序的了。整体而言可以达到优化的效果我们实现后可以进行性能测试的对比
3️⃣ 希尔排序的时间复杂度并不好计算因为 gap 的取值方法很多导致很难去计算因此在好些数中给出的希尔排序的时间复杂度都不固定官方给出的时间复杂度是 O(N1.3)
4️⃣ 稳定性不稳定 选择排序
直接选择排序 核心思想
每一次从待排序的数据元素中选出最小或最大的一个元素存放在序列的起始位置直到全部待排序的数据元素排完 。
❗ 过程❕
1️⃣ 在元素集合 array[i] - array[n-1] 中选择关键码最大 (小) 的数据元素
2️⃣ 若它不是这组元素中的最后一个(或第一个)元素则将它与这组元素中的最后一个或第一个元素交换
3️⃣ 在剩余的 array[i] - array[n-2] (array[i1]–array[n-1]) 集合中重复上述步骤直到集合剩余 1 个元素
❗ 直接选择排序的特性总结❕
1️⃣ 直接选择排序思考非常好理解但是效率不是很好。实际中很少使用
2️⃣ 时间复杂度O(N^2) - 最好 / 最坏都是如此当数据极其无序时比冒泡排序还要拉跨
3️⃣ 空间复杂度O(1)
4️⃣ 稳定性不稳定
❗ 动图演示❕ 代码实现 //与上述动图一样的代码
void Swap(int* px, int* py)
{int temp *px;*px *py;*py temp;
}
void SelectSort(int* a, int n)
{int i 0;int begin 0;while (begin n){int mini begin;//选最小for (i begin; i n; i){if (a[i] a[mini]){mini i;}}//交换Swap(a[begin], a[mini]);//迭代begin;}
}//优化版本最大值最小值同时找
void SelectSort(int* a, int n)
{int begin 0, end n - 1;while (begin end){//一趟排序将最大数最小数的下标都初始化成beginint mini begin, maxi begin;//遍历数组找到最大数和最小数的下标for (int i begin 1; i end; i){if (a[i] a[mini]){mini i;}if (a[i] a[maxi]){maxi i;}}Swap(a[begin], a[mini]);//如果没有这个if判断最大值的下标指向会随着begin的mini的交换使得max的值丢失//当maxibegin时maxi指向min下一次交换就会出问题if (maxi begin){maxi mini;}Swap(a[end], a[maxi]);//迭代begin;--end;}
}堆排序 核心思想
堆排序 (Heapsort) 是指利用堆积树 (堆) 这种数据结构所设计的一种排序算法它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆排降序建小堆。
❗ 堆排序的特性总结❕
1 堆排序使用堆来选数效率就高了很多。
2. 时间复杂度O(N*logN)
3.空间复杂度O(1)
4.稳定性不稳定
void Swap(int* px, int* py)
{int temp *px;*px *py;*py temp;
}
//向上调整算法
void AdjustUp(int*a,int child)
{int parent(child-1)/2;while(child 0){//这里的符号决定调整为大堆还是小堆这里以大堆为例if(a[child]a[parent]){Swap(a[child],a[parent]);childparent;parent(child-1)/2;}else{break;}}
}
//向下调整算法
void AdjustDown(int* a, int size, int parent)
{int child parent * 2 1;while (child size){//假设左孩子小如果假设错了更新一下//这样操作后,child指向的就是两个孩子中较小的那一个if (a[child1] a[child] child 1 size){ child;}//如果孩子大就交换决定了大堆还是小堆if (a[child] a[parent]){Swap(a[child], a[parent]);//交换后更新下标parent child;child parent * 2 1;}else{break;}}
}
//排升序
void HeapSort(int* a, int n)
{//建大堆for(int i0;in;i){AdjustUp(a,i); }int endn-1;while(end0){//交换后最大的数就排好了Swap(a[0],a[end]);//将前面的数再调整选出次小的数AdjustDown(a,end,0);end--;}
}方法二用向下调整算法建堆
void Swap(int* px, int* py)
{int temp *px;*px *py;*py temp;
}//排升序
void HeapSort(int* a, int n)
{//建大堆int i 0;//n-1就是最后一个元素下标再-1除以二就是其父节点也就是倒数第一个非叶子节点//从这开始从下往上向下建堆for (i (n - 1 - 1) / 2; i 0; i--){AdjustDown(a, n, i);}int end n - 1;//交换并删除堆中最后一个元素while (end 0){//首尾交换Swap(a[0], a[end]);//重新建大堆AdjustDown(a, end, 0);end--;}
} 倒着调整叶子节点不需要处理因为叶子节点没有子节点无法向下比较从倒数第一个非叶子节点开始即最后一个节点的父节点开始调整从下往上向下建堆。 在HeapSort函数中第一个循环调用了AdjustDown函数将待排序数组构建成了一个大堆。但是这个大堆并不是完全有序的只是满足了大堆的性质即每个节点的值都大于或等于其左右子节点的值。因此需要进行第二个while循环将大堆根中的元素依次取出交换堆顶元素和数组末尾元素并重新调整大堆直到整个数组有序。 第二个while循环中将堆顶元素与数组末尾元素交换然后将剩余元素重新调整为大根堆。这样每次交换后数组末尾的元素就是当前大根堆中的最大值而剩余元素仍然满足大根堆的性质。重复以上步骤直到整个数组有序。 交换排序
冒泡排序 // 时间复杂度O(N^2)
// 最好情况是多少O(N)
void BubbleSort(int* a, int n)
{for (int j 0; j n; j){//定义exchange可以优化冒泡排序当数据已经有序时可以提前结束排序bool exchange false;for (int i 1; i n-j; i){if (a[i - 1] a[i]){Swap(a[i - 1], a[i]);exchange true;}}if (exchange false)break;}快速排序 核心思想
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法其基本思想为任取待排序元素序列中的某元素作为基准值按照该排序码将待排序集合分割成两子序列左子序列中所有元素均小于基准值右子序列中所有元素均大于基准值然后最左右子序列重复该过程直到所有元素都排列在相应位置上为止。
❗ 过程❕
霍尔版本 1️⃣ 选出一个关键字 key一般是头或者尾
2️⃣ 经过一次单趟后key 放到了正确的位置key 左边的值比 key 小key 右边的值比 key 大
3️⃣ 再让 key 的左边区间有序、key 的右边区间有序 为什么相遇的位置的数不会比key大呢 因为右边先走!!! 我们来分析一波首先要明确R的任务是找小数L的任务是找大数相遇无非就分两种情况 1.R遇到L这种情况下又分两种 第一种情况L指向begin开始的位置压根没动这样当R走来是相遇于key这个位置二者相等并不影响排序结果 第二种情况R成功找到一个比key小的数L也成功找到一个比key大的数按照快排规则此时L和R指向的数应该交换了那么在交换后L位置的数就比key要小了这个过程可能不止一趟最终R会与L相遇在L位置这个位置的数必定是比key要小的 2.L遇到R因为刚开始是R先走的那么R停下一定是遇到了比key要小的数这个过程也可能不止一次然后L开始向右走与R在R位置相遇这个位置的值一定是比key要小的 //简易版本
QuickSort(int* a,int begin,int end)
{if(beginend)return;//注意left的起始位置如果这里leftbegin1当数组有序时会出Bugint keyibegin,leftbegin,rightend;while(leftright){//右边找小//注意循环条件的控制while(leftrighta[right]a[keyi]){right--;} //左边找大while(leftrighta[left]a[keyi]){left;}Swap(a[left],a[right]);}Swap(a[left],a[keyi]);//更新下一次递归时区间边界keyileft;//与二叉树的先序遍历有异曲同工之妙QuickSort(a,begin,keyi-1);QuickSort(a,keyi1,end);
}上述代码每次递归都将keyi的值给成begin左边在最坏情况下时间复杂度会成为ON^2并且调用函数次数与数据个数密切相关当待排序的数组数据过多时会出现栈溢出导致被覆盖的内存区域中的数据损坏从而导致程序崩溃或运行不正常。 要想优化上述情况就要使得每次选取的key尽量在中间我们可以选begin,end,midi三个下表对应数组中的值的中位数用GetMidi函数分装返回中间值的下标然后在主函数中交换a[begin]和a[midi]的值这样操作后a[begin]的值在整个数组中处于更居中的位置再递归子区间就会缩短递归的区间长度和次数大大优化代码。 //优化代码
//三数取中函数
int GetMidi(int* a, int begin, int end)
{int midi (begin end) / 2;// begin end midi三个数选中位数if (a[begin] a[midi]){if (a[midi] a[end])return midi;else if (a[begin] a[end])return begin;elsereturn end;}else//a[begin] a[midi]{if (a[midi] a[end])return midi;else if (a[begin] a[end])return end;elsereturn begin;}
}void QuickSort(int* a, int begin, int end)
{if (begin end)return;int midi GetMidi(a, begin, end);Swap(a[midi], a[begin]);int left begin, right end;int keyi begin;while (left right){// 右边找小while (left right a[right] a[keyi]){--right;}// 左边找大while (left right a[left] a[keyi]){left;}Swap(a[left], a[right]);}Swap(a[left], a[keyi]);keyi left;// [begin, keyi-1] keyi [keyi1, end]QuickSort(a, begin, keyi - 1);QuickSort(a, keyi 1, end);
}对于优化后的代码还存在小区间占用过多栈空间的问题如下图假定在理想递归情况下我们每次寻找的key都排到了数组中间那么递归的函数栈空间展开就是一颗二叉树当我们递归到二叉树后三层之后开辟的栈空间居然占了整棵树的87.5% 然而后三层需要排的数据个数并不多根本不需要浪费这么多空间我们可以针对后三层单独采用插入排序进行再优化。 //对小区间处理的插入排序函数
void InsertSort(int* a, int n)
{//注意这里的n-1for (int i 0; i n-1; i){int end i;int tmp a[end 1];while (end 0){if (tmp a[end]){//后移数组a[end 1] a[end];end--;}else{break;}}a[end 1] tmp;}
}
//找中位数函数
int GetMidi(int* a, int begin, int end)
{int midi (begin end) / 2;// begin end midi三个数选中位数if (a[begin] a[midi]){if (a[midi] a[end])return midi;else if (a[begin] a[end])return begin;elsereturn end;}else//a[begin] a[midi]{if (a[midi] a[end])return midi;else if (a[begin] a[end])return end;elsereturn begin;}
}
//快排函数
void QuickSort(int* a, int begin, int end)
{if (begin end)return;//end-begin1是数据个数规定其小于10时采用插入排序if(end-begin110)//注意这里的递归起始区间位置是abeginInsertSort(abegin,end-begin1);else{int midi GetMidi(a, begin, end);Swap(a[midi], a[begin]);int left begin, right end;int keyi begin;while (left right){// 右边找小while (left right a[right] a[keyi]){--right;}// 左边找大while (left right a[left] a[keyi]){left;}Swap(a[left], a[right]);}Swap(a[left], a[keyi]);keyi left;// [begin, keyi-1] keyi [keyi1, end]QuickSort(a, begin, keyi - 1);QuickSort(a, keyi 1, end);}
}下图是测试优化小区间后的快排效果数字代表跑完程序所用的毫秒数测试方法文末附有我们对由10万个随机数构成的数组进行排序为了使得对比更明显我们在debug调试版本下进行对比debug下每个函数栈帧添加了许多调试信息占用的空间更大小区间优化的效果更加明显。而release发布版本对调试信息进行了优化函数栈帧过多影响不大多敲的代码可能还会降低排序速度起到适得其反的效果。 可以看到效果是有的但是不是非常明显想要大幅度改进还需要从思想上改变的新的方法 为了方便和后续新的方法对比我们把霍尔版本的单趟排序抽离出来定义为PartSort1函数
int PartSort1(int* a, int begin, int end)
{int midi GetMidi(a, begin, end);Swap(a[midi], a[begin]);int left begin, right end;int keyi begin;while (left right){// 右边找小while (left right a[right] a[keyi]){--right;}// 左边找大while (left right a[left] a[keyi]){left;}Swap(a[left], a[right]);}Swap(a[left], a[keyi]);return left;
}
//函数 PartSort1 返回了 left 指针指向的值
//这个值表示基准值在分区后的位置。在快速排序算法中
//这个值会被用来确定下一次分区的区间范围。
void QuickSort(int* a, int begin, int end)
{if (begin end)return;//end-begin1是数据个数规定其小于10时采用插入排序if(end-begin110)//注意这里的递归起始区间位置是abeginInsertSort(abegin,end-begin1);else{int keyiPartSort1(a,begin,end);QuickSort(a, begin, keyi - 1);QuickSort(a, keyi 1, end);}
}补坑位版本
动图展示 注意不同方法的快速排序第一趟排序的结果可能不同 //补坑位版本
int PartSort2(int* a,int begin,int end)
{int midiGetMidi(a, begin, end);Swap(a[midi],a[begin]);int keya[begin];int holebegin;while(beginend){//右边找小找到后填到左边坑位while(beginend keya[end]){end--;} a[hole]a[end];holeend;//左边找大找到后填到右边坑位while(beginendkeya[begin]){begin;}a[hole]a[begin];holebegin;}a[hole]key;return hole;
}前后指针版本 第一趟交换后的结果 最开始prev和cur相邻的当cur遇到比key小的值perv交换prev和cur位置的值当cur遇到比key的大的值以后curprev和cur之间的值都是比key大的值prev之前的包括交换后prev上的值都比key小相当于把大的翻滚式往右边推同时把小的换到左边 int PartSort3(int*a,int begin,int end)
{int midiGetMidi(a,begin,end);Swap(a[begin],a[midi]);int prevbegin;int curprev1;int keya[begin];while(curend){if(keya[cur]){cur;}else{prev;Swap(a[prev],a[cur]); cur;}}Swap(a[prev],key);return prev;
}ok了这个测试后也没啥问题
int PartSort3(int* a, int begin, int end)
{int midi GetMidi(a, begin, end);Swap(a[midi], a[begin]);int keyi begin;int prev begin;int cur prev 1;while (cur end){//循环内部其实还可以进一步简化代码if (a[cur] a[keyi] prev ! cur)Swap(a[prev], a[cur]);cur;}Swap(a[prev], a[keyi]);keyi prev;return keyi;
}非递归版本 通常我们将递归代码改为非递归有两种方式 写成循环版本借助数据结构----栈 如果想将快排仅仅利用循环是不现实的因为递归的子区间左右区间不好控制这里我们需要借助栈的结构 1️⃣将begin和end压入栈中利用单趟快排找到keyi并且pop掉这两个元素 2️⃣将由keyi分出的子区间压入栈中并且让每次将出栈的左右区间的子区间进栈 3️⃣循环多次 4️⃣当分出的子区间左区间大于等于右区间不需要入栈 void QuickSortNonR(int* a, int begin, int end)
{ST s;STInit(s);//第一次入栈要将整个数组的左右区间进栈STPush(s, end);STPush(s, begin);while(!STEmpty(s)){//记录左右区间后出栈int left STTop(s);STPop(s);int right STTop(s);STPop(s);//利用存好的左右区间进行一趟快排找到keyiint keyi PartSort3(a, left, right);// [left, keyi-1] keyi [keyi1, right]//当子区间合法时继续入栈if (left keyi - 1){STPush(s, keyi - 1);STPush(s, left);}if (keyi 1 right){STPush(s, right);STPush(s, keyi1);}}STDestroy(s);
}归并排序 基本思想 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并得到完全有序的序列即先使每个子序列有序再使子序列段间有序。若将两个有序表合并成一个有序表称为二路归并。 动图展示✨ 递归版本
void _MergeSort(int* a, int begin, int end, int* tmp)
{if (begin end)return;int mid (begin end) / 2;// [begin, mid][mid1, end]_MergeSort(a, begin, mid, tmp);_MergeSort(a, mid1, end, tmp);// [begin, mid][mid1, end]归并int begin1 begin, end1 mid;int begin2 mid 1, end2 end;int i begin;while (begin1 end1 begin2 end2){if (a[begin1] a[begin2]){tmp[i] a[begin1];}else{tmp[i] a[begin2];}}while(begin1 end1){tmp[i] a[begin1];}while (begin2 end2){tmp[i] a[begin2];}//将tmp数组中的值拷贝回去memcpy(a begin, tmp begin, sizeof(int) * (end - begin 1));
}void MergeSort(int* a, int n)
{int* tmp (int*)malloc(sizeof(int) * n);if (tmp NULL){perror(malloc fail);return;}_MergeSort(a, 0, n - 1, tmp);free(tmp);
}小结 主函数接受两个参数一个整数数组a和一个整数nn 表示数组的长度。 MergeSort 函数首先为tmp数组开辟待空间。 调用_MergeSort函数进行排序。 释放tmp的空间。 在子函数中首先计算中间位置mid并递归地对数组的两部分进行排序。这是分治的思想将大问题分解成小问题使用四个指针begin1和begin2、end1和end2分别指向两个部分的开始位置和结束位置 然后看三个while循环的比较插入过程每次分割后两部分分别从头开始比较把较小的插入tmp数组某一部分的数全部插入数组后结束第一个while循环。继续检查哪个数组还有剩余元素剩下的都是较大的直接插入tmp数组中。 接下来我们需要从最小的子序列到最大依次往上进行排序插入所以这里引用递归的思想完成排序 在函数_MergeSort中首先判断begin是否等于end如果相等则当前子序列只有一个元素不需要排序直接返回。 如果不相等则计算中间位置mid然后递归调用_MergeSort函数对左半部分和右半部分进行排序。在排序完成后将左半部分和右半部分合并成一个有序数组tmp。 每层递归排序后使用memcpy函数将临时数组tmp中的元素复制回原数组a中。
非递归版本 归并排序不适合用栈来改造归并排序类似于树的后序遍历在返回时还需要合并这样的复杂操作栈模拟递归是不能实现的对比之前的快速排序的非递归版本快速排序是前序遍历即使返回时不做任何操作也可以达到排序目的。我们可以先将gap初始化为1然后每次将gap乘以2直到gap大于等于数组的长度为止。在每次循环中我们将数组分成若干个大小为gap的子数组然后对每个子数组进行排序和合并。这样我们就可以通过循环来实现归并排序而不需要使用递归。 void MergeSortNonR(int* a, int n)
{int* tmp (int*)malloc(sizeof(int) * n);if (tmp NULL){perror(malloc fail);return;}//通过gap控制归并的子数组大小实现非递归的归并排序int gap 1;while (gap n){printf(gap:%2d-, gap);for (size_t i 0; i n; i 2 * gap){int begin1 i, end1 i gap - 1;int begin2 i gap, end2 i 2 * gap - 1;// 边界的处理if (end1 n || begin2 n){break;}if (end2 n){end2 n - 1;}//开始归并int j begin1;while (begin1 end1 begin2 end2){if (a[begin1] a[begin2]){tmp[j] a[begin1];}else{tmp[j] a[begin2];}}while (begin1 end1){tmp[j] a[begin1];}while (begin2 end2){tmp[j] a[begin2];}memcpy(a i, tmp i, sizeof(int) * (end2-i1));}printf(\n);gap * 2;}free(tmp);
} 性能测试
void TestInsertSort()
{int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };InsertSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}void TestBubbleSort()
{int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };BubbleSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}void TestShellSort()
{//int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };int a[] { 13, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };ShellSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}void TestSelectSort()
{//int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };int a[] { 13, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1};SelectSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}void TestHeapSort()
{//int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };int a[] { 13, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };HeapSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}void TestQuickSort()
{//int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };//int a[] {6,1,2,7,9,3,4,5,10,8};int a[] { 6,1,2,6,7,9,3,4,6,10,8 };PrintArray(a, sizeof(a) / sizeof(int));//QuickSort(a, 0, sizeof(a) / sizeof(int)-1);QuickSortNonR(a, 0, sizeof(a) / sizeof(int) - 1);PrintArray(a, sizeof(a) / sizeof(int));
}void TestMergeSort()
{//int a[] { 3, 2, 6, 8, 4, 6, 0, 9, 5, 7, 1 };//int a[] {6,1,2,7,9,3,4,5,10,8};//int a[] { 6,1,2,6,7,9,3,4,6,10,8 };int a[] { 10,8,7,1,3,9,4,2,9,10,1,1,2,3};PrintArray(a, sizeof(a) / sizeof(int));MergeSortNonR(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}void TestCountSort()
{int a[] {1,3,9,1,5,1,2,3,-5,-5,-2 };PrintArray(a, sizeof(a) / sizeof(int));CountSort(a, sizeof(a) / sizeof(int));PrintArray(a, sizeof(a) / sizeof(int));
}// 测试排序的性能对比
void TestOP()
{srand(time(0));const int N 10000000;int* a1 (int*)malloc(sizeof(int) * N);int* a2 (int*)malloc(sizeof(int) * N);int* a3 (int*)malloc(sizeof(int) * N);int* a4 (int*)malloc(sizeof(int) * N);int* a5 (int*)malloc(sizeof(int) * N);int* a6 (int*)malloc(sizeof(int) * N);int* a7 (int*)malloc(sizeof(int) * N);int* a8 (int*)malloc(sizeof(int) * N);for (int i 0; i N; i){a1[i] rand();a2[i] a1[i];a3[i] a1[i];a4[i] a1[i];a5[i] a1[i];a6[i] a1[i];a7[i] a1[i];a8[i] a1[i];}int begin1 clock();//InsertSort(a1, N);int end1 clock();int begin2 clock();ShellSort(a2, N);int end2 clock();int begin3 clock();//SelectSort(a3, N);int end3 clock();int begin4 clock();HeapSort(a4, N);int end4 clock();int begin5 clock();QuickSort(a5, 0, N - 1);int end5 clock();int begin6 clock();MergeSort(a6, N);int end6 clock();int begin7 clock();//BubbleSort(a7, N);int end7 clock();int begin8 clock();CountSort(a8, N);int end8 clock();printf(InsertSort:%d\n, end1 - begin1);printf(ShellSort:%d\n, end2 - begin2);printf(SelectSort:%d\n, end3 - begin3);printf(HeapSort:%d\n, end4 - begin4);printf(QuickSort:%d\n, end5 - begin5);printf(MergeSort:%d\n, end6 - begin6);printf(BubbleSort:%d\n, end7 - begin7);printf(CountSort:%d\n, end8 - begin8);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);free(a8);
}int main()
{//TestInsertSort();//TestBubbleSort();//TestShellSort();//TestSelectSort();//TestHeapSort();//TestQuickSort();//TestMergeSort();//TestCountSort();TestOP();return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910768.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!