小语种服务网站定制微信小程序开发价格
web/
2025/10/7 10:07:59/
文章来源:
小语种服务网站,定制微信小程序开发价格,企业网站托管方案内容具体有哪些,商丘做网站公司新站seo快速收录网页内容页的方法作者主页#xff1a;作者主页 数据结构专栏#xff1a;数据结构 创作时间 #xff1a;2024年5月18日 前言#xff1a;
今天我们就给大家带来几种排序的讲解#xff0c;包括冒泡排序#xff0c;插入排序#xff0c;希尔排序#xff0c;选择排序#xff0c;堆排序… 作者主页作者主页 数据结构专栏数据结构 创作时间 2024年5月18日 前言
今天我们就给大家带来几种排序的讲解包括冒泡排序插入排序希尔排序选择排序堆排序快速排序等等在讲解之前我先给大家一个网站用于查看各种排序的动图这样有助于我们更加清晰的去了解各种排序排序动图
冒泡排序
首先我们来讲解一下冒泡排序这是我们学习编程第一个接触到的排序也是较为容易理解的一个排序下面我们来看一下她是如何实现的。 这就是一个大概的冒泡排序的实现过程其实就是每次都把最大的一个放到最后面然后下一轮就不需要去管后面最大的那几个。
下面我们来看一下代码应如何实现
#includestdio.h
#includeiostream
#includealgorithm
using namespace std;void print(int* arr, int n)
{for (int i 0; i n; i) {printf(%d , arr[i]);}
}int main()
{int arr[] { 23,235,13,123523,2342,2342,1,41523,3456,6547,546 };int n sizeof(arr) / sizeof(arr[0]);for (int i 0; i n - 1; i){for (int j 0; j n - 1 - i; j) {if (arr[j] arr[j 1]) { swap(arr[j], arr[j 1]);}}}print(arr, n);return 0;
}
这就是冒泡排序实现的过程这里我们就不过多的去说了还是比较简单的。 时间复杂度最坏情况O(N^2) 最好情况O(N) 空间复杂度O(1) 插入排序
下面我们来看一下插入排序插入排序的步骤大概是这样的。
1.从第一个元素开始该元素可以认为已经被排序 2.取下一个元素tem从已排序的元素序列从后往前扫描 3.如果该元素大于tem则将该元素移到下一位 4.重复步骤3直到找到已排序元素中小于等于tem的元素 5.tem插入到该元素的后面如果已排序所有元素都大于tem则将tem插入到下标为0的位置 6.重复步骤2~5
图像演示 这个图像还是比较清晰易懂的下面我们来看一下代码吧。
void InsertSort(int* arr, int n)
{for (int i 0; i n - 1; i){int end i;int temp arr[end 1];while (end 0){if (temp arr[end]){arr[end 1] arr[end];end--;}else{break;}}arr[end 1] temp;}
} 插入排序其实就是我们从第一个开始然后我们用tmp记录要被插入的元素然后一直和前面的作比较如果大于前面的那么就结束如果小于前面的我们就令end1的位置等于end然后end--就可以了最后再将temp放到不符合这个条件的位置就完成了一轮插入排序后面也是这样循环进行的。 时间复杂度最坏情况下为O(N*N)此时待排序列为逆序或者说接近逆序 最好情况下为O(N)此时待排序列为升序或者说接近升序。 空间复杂度O(1) 希尔排序
下面我们来讲一下希尔排序这个排序其实是比较难懂的但他的时间复杂度也是较为小的下面我们看一下如何实现这个排序
大致步骤 1.先选定一个小于N的整数gap作为第一增量然后将所有距离为gap的元素分在同一组并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量重复上述操作… 2.当增量的大小减到1时就相当于整个序列被分到一组进行一次直接插入排序排序完成。 代码
void ShellSort(int* arr, int n)
{int gap n;while (gap 1){gap / 2;for (int i 0; i n - gap; i){int end i;int temp arr[end gap];while (end 0){if (temp arr[end]){arr[end gap] arr[end];end - gap;}else{break;}}arr[end gap] temp;}}
}时间复杂度平均O(N^1.3) 空间复杂度O(1) 选择排序
思路
每次从待排序列中选出一个最小值然后放在序列的起始位置直到全部待排数据排完即可。 实际上我们可以一趟选出两个值一个最大值一个最小值然后将其放在序列开头和末尾这样可以使选择排序的效率快一倍。
下面我们来看一下动图 这里我们图片仅供参考因为我们要用两个下标一个最大值一个最小值以此来提高效率。
void SelectSort(int* arr, int n)
{int begin 0, end n - 1;while (begin end){int max begin, min begin;for (int i begin; i end; i){if (arr[i] arr[min]){min i;}if (arr[i] arr[max]){max i;}}swap(arr[begin], arr[min]);//为防止最大值在begin位置被换走我们还要加个判断if (begin max){max min;}swap(arr[max], arr[end]);begin;--end;}
}时间复杂度最坏情况O(N^2) 最好情况O(N^2) 空间复杂度O(1) 堆排序
想要更好的了解堆排可以查看这篇博文堆
在学习堆排之前首先我们要知道社么是堆堆其实就是一个二叉树然后有大根堆和小根堆然后他们分别长这样 然后我们这里排序的思路就是比如说大根堆他的最大值一定在堆顶然后我们就让他和最后一个数交换然后不再去管他再得到一个新的大根堆继续进行这个操作这样是不是就实现了呢。
然后这里我们首先还要建堆然后我们升序的话就建大堆直接把最大的放在最后一个然后就不把他看作堆里的数据了。反之降序就建小堆。下面我们先来看一下如何建堆。
//向上调整(小根堆)
void AdjustUp(HPDataType* a, int child)
{int parent (child - 1) / 2;while (child0){//if (a[child] a[parent])//小于就换就相当于建小堆if (a[child] a[parent])//大于就换就会变成大堆{std::swap(a[child], a[parent]);child parent;parent (child - 1) / 2;}else{break;}}
}//建堆
void HPPush(HP* php, HPDataType x)
{assert(php);if (php-size php-capacity){int newcapacity php-capacity 0 ? 4 : php-capacity * 2;HPDataType* tmp (HPDataType*)realloc(php-a,sizeof(HPDataType) * newcapacity);if (tmp NULL){perror(realloc failed!!!);return;}php-a tmp;php-capacity newcapacity;}php-a[php-size] x;//向上调整AdjustUp(php-a, php-size - 1);
}
这就是c语言种建堆的一个过程还是比较麻烦的。
然后有了堆之后排序就比较简单了。
void HeapSort(int* a, int n)
{//首先建堆//升序建大堆//降序建小堆/*for (int i0;in;i){AdjustUp(a, i);}*/// 求最后一个节点的父亲for (int i (n - 1 - 1) / 2; i 0; i--){AdjustDown(a, n, i);}int end n - 1;///这里0即可因为0时只剩下最后一个就不再需要继续进行了while (end0)//思路就是比如我们升序排序那么我们就利用大根堆每次都将最大的那个数放在最顶上然后将它和最后一个交换然后让整体的大小--那么最后一个就不再会受影响{std::swap(a[0], a[end]);AdjustDown(a, end, 0);--end;}} 堆排最好的最坏的时间复杂度均为O(n*logn) 空间复杂度为O(1) 快速排序
快排还是这几个排序种比较麻烦的有一个但其实也是比较好用的一个
我们这里将会用三种方法来实现这个快速排序
hoare版本(左右指针法)
思路 1、选出一个key一般是最左边或是最右边的。 2、定义一个begin和一个endbegin从左向右走end从右向左走。需要注意的是若选择最左边的数据作为key则需要end先走若选择最右边的数据作为key则需要bengin先走。 3、在走的过程中若end遇到小于key的数则停下begin开始走直到begin遇到一个大于key的数时将begin和right的内容交换end再次开始走如此进行下去直到begin和end最终相遇此时将相遇点的内容与key交换即可。选取最左边的值作为key 4.此时key的左边都是小于key的数key的右边都是大于key的数 5.将key的左序列和右序列再次进行这种单趟排序如此反复操作下去直到左右序列只有一个数据或是左右序列不存在时便停止操作此时此部分已有序 //快速排序 hoare版本(左右指针法)
void QuickSort(int* arr, int begin, int end)
{//只有一个数或区间不存在if (begin end)return;int left begin;int right end;//选左边为keyint keyi begin;while (begin end){//右边选小 等号防止和key值相等 防止顺序begin和end越界while (arr[end] arr[keyi] begin end){--end;}//左边选大while (arr[begin] arr[keyi] begin end){begin;}//小的换到右边大的换到左边swap(arr[begin], arr[end]);}swap(arr[keyi], arr[end]);keyi end;//[left,keyi-1]keyi[keyi1,right]QuickSort(arr, left, keyi - 1);QuickSort(arr,keyi 1,right);
}挖坑法
递归
挖坑法思路与hoare版本(左右指针法)思路类似1.选出一个数据一般是最左边或是最右边的存放在key变量中在该数据位置形成一个坑2、还是定义一个L和一个RL从左向右走R从右向左走。若在最左边挖坑则需要R先走若在最右边挖坑则需要L先走 //快速排序法 挖坑法
void QuickSort1(int* arr, int begin, int end)
{if (begin end)return;int left begin,right end;int key arr[begin];while (begin end){//找小while (arr[end] key begin end){--end;}//小的放到左边的坑里arr[begin] arr[end];//找大while (arr[begin] key begin end){begin;}//大的放到右边的坑里arr[end] arr[begin];}arr[begin] key;int keyi begin;//[left,keyi-1]keyi[keyi1,right]QuickSort1(arr, left, keyi - 1);QuickSort1(arr, keyi 1, right);
}非递归
//单趟排
int PartSort(int* arr, int begin, int end)
{int key arr[begin];while (begin end){while (key arr[end] begin end){--end;}arr[begin] arr[end];while (key arr[begin] begin end){begin;}arr[end] arr[begin];}arr[begin] key;int meeti begin;return meeti;
}void QuickSortNoR(int* arr, int begin, int end)
{stackint st;//先入右边st.push(end);//再入左边st.push(begin);while (!st.empty()){//左区间int left st.top();st.pop();//右区间int right st.top();st.pop();//中间数int mid PartSort(arr, left, right);//当左区间mid-1则证明左区间已经排好序了if (left mid - 1){st.push(mid - 1);st.push(left);}//当mid1右区间则证明右区间已经排好序if (right mid 1){st.push(right);st.push(mid 1);}}
}前后指针法
思路 1、选出一个key一般是最左边或是最右边的。 2、起始时prev指针指向序列开头cur指针指向prev1。 3、若cur指向的内容小于key则prev先向后移动一位然后交换prev和cur指针指向的内容然后cur指针若cur指向的内容大于key则cur指针直接。如此进行下去直到cur到达end位置此时将key和prev指针指向的内容交换即可。
经过一次单趟排序最终也能使得key左边的数据全部都小于keykey右边的数据全部都大于key。
然后也还是将key的左序列和右序列再次进行这种单趟排序如此反复操作下去直到左右序列只有一个数据或是左右序列不存在时便停止操作
//快速排序法 前后指针版本
void QuickSort2(int* arr, int begin, int end)
{if (begin end)return;int cur begin, prev begin - 1;int keyi end;while (cur ! keyi){if (arr[cur] arr[keyi] prev ! cur){swap(arr[cur], arr[prev]);}cur;}swap(arr[prev],arr[keyi]);keyi prev;//[begin,keyi -1]keyi[keyi1,end]QuickSort2(arr, begin, keyi - 1);QuickSort2(arr, keyi 1, end);}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88409.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!