网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
2.选择排序
**首先i****等于0,**每次i++,并从i轮询到末尾,选择一个最小者与第i个位置进行交换.
比如:
16,8,21,10,49
第1次遍历整个数组,找到最小值8,则与arr[0]进行交换:
8,16,21,10,49
第2次遍历下标1~4的数组,找到10,则与arr[1]进行交换:
8,10 ,21,16,49
第3次遍历下标2~4的数组,找到16,则与arr[2]进行交换:
8,10 , 16, 21,49
第4次遍历下标3~4的数组,找到21,由于交换的位置相等,则保持不变
由于第5次,起始小标等于n-1了.所以已经比较完了.则结束了.
所以代码如下所示:
template <typename T>
void mySwap(T& a, T& b) // 交换函数
{
T c(a);
a = b;
b = c;
}
template <typename T>
void seleteSort(T arr[], int len, bool ascend = true) // ascend为ture表示升序
{
for (int i = 0; i < len -1; ++i) {
int minIdx = i;
for (int j = i+1; j < len; ++j) {
if (ascend ? (arr[minIdx] > arr[j]) : (arr[minIdx] < arr[j])) {
minIdx = j;
}
}
if (minIdx != i) {
mySwap(arr[i], arr[minIdx]);
}
}
}
测试代码如下所示:
int arr[8] = {25, 22, 12, 8, 9, 11, 30 ,40};
bubbleSort(arr, 8);
cout<<"ascend: "<<endl;
for (int i = 0; i < 8; ++i) {
cout<<i<<": "<<arr[i]<<endl;
}
bubbleSort(arr, 8, false);
cout<<"descend: "<<endl;
for (int i = 0; i < 8; ++i) {
cout<<i<<": "<<arr[i]<<endl;
}
打印如下所示:
总结:
选择排序是不稳定的排序算法,例如 **[3, 4, 3, 1, 5]**这个数组,第一次交换,第一个3和1交换位置,此时原来两个3的相对位置发生了变化,所以无法保证值相等的元素的相对位置不变,
3.冒泡排序
重复len次冒泡,每次冒泡都是**(int j=len-1; j>i; j–)从数组末尾往前进行冒泡,如果arr[j-1]>arr[j],则将arr[j]与arr[j-1]**交换,让值小的冒泡上去.
代码如下所示:
template < typename T >
static void bubbleSort(T arr[], int len, bool ascend = true)
{
bool isSwap = true;
for(int i=0; (i<len) && isSwap; i++) // 每次冒泡时,则判断上次是否发生过交换,如果交换过,那说明还不是个有序的表
{
isSwap = false; // 每次冒泡的时候复位 “交换标志位”
for(int j=len-1; j>i; j--)
{
if( ascend ? ( arr[j-1] > arr[j] ) : (arr[j-1] < arr[j] ) ) // 如果是升序,arr[j-1] > arr[j],则将arr[j]从末尾冒泡冒上去
{
mySwap(arr[j], arr[j-1]);
isSwap = true; // “交换标志位” 设置为true
}
}
}
}
PS: 由于mySwap()函数和测试代码已经写过了,后面就不再重复写了。
总结:
冒泡排序是稳定的排序算法,因为每次都是冒泡相邻比较,比如升序,如果后者>=前者,是不会进行交换
4.插入排序
将一个数组分为两个部分,左边是排序好的,右边是未排序的.
然后每次提取一个右边的数据出来,然后轮询左边(排序好的),如果找到合适的位置(前者小于它且后者大于它),则插入进去.如果未找到,则插入在左边排序好的末尾位置.
比如16,8,21,10,49,由于左边默认会有一个数值(一个数值无需判断比较),所以无需判断arr[0]:
**16 | 8,21,10,49 ( |****左边是排序好的,**右边是等待排序的 )
**第1****次,****获取arr[1],由于8小于16,插入在16前面,**所以插入后:
8,16 | 21,10,49
**第2****次,****获取arr[2],****向前轮询,****由于21>16,**所以停止向前遍历, **并且位置没改变过,**所以无需操作:
8,16,21 | 10,49
**第3****次,**获取arr[3], **向前轮询,****由于10<21,则21向后挪位,****再继续向前轮询,****由于10<16,则16向后挪位,**最后10>=8,则插入在8后面:
8, 10,16,21 | 49
**第4****次,****获取arr[4],****由于49>21,**所以停止向前遍历, 并且位置没改变过,所以无需操作最终为:
8, 10,16,21 ,49
代码如下所示:
template < typename T >
static void insertSort(T arr[], int len, bool ascend = true)
{
for(int i=1; i<len; i++) // 循环取出右边未排序的
{
int k = i;
T temp = arr[i]; // 把值取出来,后面会进行挪位操作,会覆盖掉arr[i]原来的内容
// 如果ascend为true,则表示升序,那么当后者大于前者时,则停止for轮询,因为左边是有序序列
for(int j=i-1; (j>=0) && (ascend ? (arr[j]>temp) : (arr[j]<temp)); j--)
{
arr[j+1] = arr[j]; // 进行先后挪位操作
k = j; // 更新要插入的位置
}
if( k != i ) // 如果未进行挪位,那么k==i,则不需要重复插入
{
arr[k] = temp;
}
}
}
总结:
插入排序是稳定的排序算法,例如 [4,3, 3, 1, 5]这个数组,由于左边的3是提前插入的[ 3, 4 | 3, 1, 5**]**,而后续的3由于>=前面的3,所以插入在后面
5.希尔排序
希尔排序是插入排序的升级版.并且比插入排序快.
希尔排序则是将一个插入排序,比如初始步长间隔gap为3,那么将会分成3个小组进行插入排序,每个小组插入排序好后,再次将步长间隔gap较少一部分再次进行插入排序,直到最后步长偏移为1后,进行整个插入排序.一般gap步长都是以 len/3+1来计算.以后每次以 gap/3+1来缩小。
PS: 也可以设置gap固定增量从 n/2 开始,以后每次缩小到原来的一半。
比如下图所示:
代码如下所示**😗*
template < typename T >
static void shellSort(T arr[], int len, bool ascend = true)
{
int gap = len;
while (gap > 1) {
gap = gap / 3 + 1; // 加一能够保证gap最后一次为1.
for(int offset = 0 ; offset < gap; ++offset) { // 对每组进行插入排序
for(int i=gap-offset; i<len; i+=gap) // 循环取出右边未排序的
{
int k = i;
T temp = arr[i]; // 把值取出来,后面会进行挪位操作,会覆盖掉arr[i]原来的内容
// 假如ascend为true,则表示升序,那么当后者大于前者时,则停止for轮询
for(int j=i-gap; (j>=0) && (ascend ? (arr[j]>temp) : (arr[j]<temp)); j-=gap)
{
arr[j+gap] = arr[j]; // 进行先后挪位操作
k = j; // 更新要插入的位置
}
if( k != i ) // 如果未进行挪位,那么k==i,则不需要重复插入
{
arr[k] = temp;
}
}
}
}
}
总结:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
g-cj9wRzXq-1715620319396)]
[外链图片转存中…(img-sIPCfN0M-1715620319397)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!