/*
File: sort.cpp
Function:
Writer:
Time: 2022-07-21
*/
/*
希望:
假如有N个数据元素,需要排序,从小到大
*/
#include <stdio.h>
#include <iostream>
//插排
//每个元素与它之前的若干元素分别进行比较,如小于它,则进行交换;
/*
插入排序(InsertionSort),一般也被称为直接插入排序。
对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增 1 的有序表
。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
*/
int insert_sort(int *value,int nsize)
{
//1. 第一层遍历,便利从第2个的元素开始,下标为1,默认第一个是有序的
int nIndex = 1;
int k = 0;
for(nIndex = 1; nIndex<nsize; nIndex++)
{
//2. 第二层遍历,并且移位(目的是小的往前移动)
int temp = value[nIndex]; //要比较的先拿出来
for(k=nIndex ; k>0; k--)
{
//如果前面的数比后面的数大,则需要后移
if(value[k-1]>temp)
{
value[k]=value[k-1]; //前面的数后移一个
//value[k-1]=temp;
}
else
break;
}
value[k]=temp;//完成插入操作(这个就是插入的实际位置)
}
return 0;
}
//冒泡排序
//每个元素同后面一个元素进行比较,将最大的元素依次后移,最终得到一个从小到大的序列
/*
int a[10] = {1,4,2,5,8,4,6,9,1,0};
a. 总共10个元素,则需要比较10-1=9个数,所以第一层循环;
b. 对a[0]排序,总共需要比较从下标 0 开始到 下标(10-1)-0;
c. 对a[1]排序,总共需要比较从下标 1 开始到 下标 (10-1)- 1; (最右边一个已经是最大)
d. 对a[2]排序,总共需要比较从下标 2 开始到 下标 (10-1) -2; (最右边2个已经排序)
......依次类推
*/
int bubble_sort(int *value,int nsize)
{
//1. 第一层遍历,遍历从第一个开始的元素,
int nIndex = 0;
for(nIndex = 0; nIndex< nsize-1; nIndex++)
{
//2. 第二层遍历,
int nBack = 0;
for(nBack = 0; nBack< nsize - 1 - nIndex; nBack++)
{
if(value[nBack] > value[nBack+1])
{
int temp = value[nBack];
value[nBack] = value[nBack+1];
value[nBack] = temp;
}
}
}
return 0;
}
/*
希尔排序
希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。
其核心是通过分组,通过比较相距一定间隔的元素来进行,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。
1. 希尔排序与元素个数的奇偶性无关,5个元素,先取步长为2,再取步长为1即可。
2. 希尔排序只要保证最终一趟的步长为1即可保证整个序列有序。其他步长的排序趟数只是为了降低比较和移动数据的次数
3. 如果只做一趟希尔排序,则其会直接退化为普通的插入排序。
*/
//将一个分组排好序后,再去处理下一个分组。
// 共gap个组,对每一组都执行直接插入排序
//0,1,2,3,4,5,6,7
//参考这边有个图,比较形象:https://blog.csdn.net/weixin_45951567/article/details/107937743
/*
例如:以下摘自网络
9,8,1,3,6,5,2,7
step = 8/2=4;由step可知分组的个数为4组:{9,6},{8,5},{1,2},{3,7},然后对每组数据进行排序,重点!!!排序过程一定要放在整体数据中进行,分组只是让排序更加方便理解!!!
最终第一次排序结果:{6,5,1,3,9,8,2,7}
6,5,1,3,9,8,2,7
step = 4/2=2;由step可知分组的个数为2组:{6,1,9,2},{5,3,8,7}
最终第二次的排序结果:{1,3,2,5,6,7,9,8}
1,3,2,5,6,7,9,8
step = 2/2=1;由step可知分组的个数为1组,也就是整体数据;
最终第三次排序结果为:{1,2,3,5,6,7,8,9}
因为这个数组总共就只有三次步长计算,所以第三次排序完成后整体数据排序也就完成(排序的次数=步长计算次数)
但是这样可能也会有人问如果数组元素的个数为奇数时怎么办,最后分组的时候会多一个元素出来,这很好解决,多出来的元素放入到第一个分组中去进行排序。
*/
int shell_sort_2(int *value, int length)
{
int gap = 0;
int i , j = 0;
for (gap = length / 2; gap >= 1;gap /= 2)
{
for(i = gap; i < length; i ++)
{
int temp = value[i];
for (j = i - gap; j >= 0 ;j = j - gap)
{
if(temp < value[j])
value[j+gap] = value[j];
else
break;
}
value[j+gap] = temp;
}
}
return 0;
}
int main(int argc,char*argv[])
{
int a[14] = {1,4,2,5,8,4,6,9,1,0,11,24,12,7};
insert_sort(a,14);
for(auto& it:a)
std::cout<<it<<std::endl;
std::cout<<"next"<<std::endl;
bubble_sort(a,14);
for(auto& it:a)
std::cout<<it<<std::endl;
std::cout<<"next"<<std::endl;
std::cout<<"next"<<std::endl;
shell_sort_2(a,14);
for(auto& it:a)
std::cout<<it<<std::endl;
getchar();
return 0;
}
2022-07-21 回顾排序算法
于 2022-07-22 10:47:43 首次发布