C++查找与排序
排序
希尔排序
希尔排序是插入排序的改进,其中最里层循环其实就是插入排序
核心思想:增量缩小排序,设待排序元素序列有n个元素,首先取一个整数increment(小于n)作为间隔将全部元素分为increment个子序列,所有距离为increment的元素放在同一个子序列中,在每一个子序列中分别实行直接插入排序。然后缩小间隔increment,重复上述子序列划分和排序工作。直到最后取increment=1,将所有元素放在同一个子序列中排序为止。
由于开始时,increment的取值较大,每个子序列中的元素较少,排序速度较快,到排序后期increment取值逐渐变小,子序列中元素个数逐渐增多,但由于前面工作的基础,大多数元素已经基本有序,所以排序速度仍然很快。
以下代码我加入了一些解释的注释以便读者更好的理解
int shell_sort(int *data, int length){
int gap = 0;
int i =0, j = 0;
int temp = 0;
///第一个for循环为分组的过程
for(gap = length/2; gap >= 1; gap /=2){
///第二个for循环为逐个组遍历
for(i = gap; i < length; i++){
temp = data[i];
///第三个for循环为组内进行插入排序,其实就是讲temp也就是data[i]插入进去
for (j = i-gap; j >= 0 && temp < data[j]; j = j - gap){
///插入的方式就是,不停的往后挪一个gap,直到temp比前面的大,比后面的小
data[j+gap] = data[j];
}
///此行就是把temp给插入到正确位置
data[j+gap] = temp;
}
}
}
归并排序
递归的方式
void merge_sort(int *arr, int left, int right)
{
if (left == right)
return;
int mid = (left + right) / 2;
merge_sort(arr, left, mid);
merge_sort(arr, mid+1, right);
merge(arr, left, mid, right);
}
void merge(int *arr, int left, int mid, int right)
{
int n = right - left + 1;
int *temp = new int[n];
int i = 0;
int lefttmp = left;
int righttmp = mid + 1;
while(lefttmp <= mid && rightmp <= right)
{
temp[i++] = arr[lefttmp] < arr[righttmp] ? arr[lefttmp++]:arr[righttmp++];
}
while(lefttmp <= mid)
{
temp[i++] = arr[lefttmp++];
}
while(righttmp <= right)
{
temp[i++] = arr[righttmp++];
}
for(int j = left; j <= right; j++)
{
arr[j] = temp[j-left];
}
}
快速排序
快速排序采用思想为分而治之
基本思想:首先选择一个数作为哨兵,即基准数。然后,将整个数组比这个哨兵大的放在右边,小的放在左边。
最后将哨兵两侧的数据重复上述过程。
具体代码实现:
选择哨兵,我们一般直接取数组第一个数作为基准数,然后开始排序
具体排序方法如下,也是算法的核心逻辑:
1.选择基准后,保存为临时变量。
2.从右侧开始于基准比较直到数据比基准小,那么将这个比基准小的数据挪到基准的位置,那么当前位置则空了出来(不用担心基准数值被覆盖,我们以前保存到了临时变量)。然后再从左侧开始向右查找,直到遇到比基准大的数字,然后将这个数字放到上轮空出的位置。然后再从右侧继续查找,循环的去填补空位,当左右都查找到了一个相同的位置,那么这个位置就是最终要填补的空位,这个空位左侧都比基准小,右侧都比基准打。没错,这个空位就给最开始基准临时变量保留的。
3.这样我们就完成了第一轮快排,然后我们将基准左侧与右侧分别继续进行快排。左侧的快排和右侧的快排里面又会继续分组快排,我们知道 递归很重要的一点是知道什么时候停下,在此处,不难发现,当递归的数组长度只有1时,无需递归,直接返回。
int quick_sort(int *arr, int start, int end)
{
int i = start, j = end;
if (i >= j)
{
return;
}
///保存基准
int temp = arr[i];
while(i != j)
{
while((i < j) && (arr[j] > temp))
{
j--;
}
if (i < j)
{
arr[i] = arr[j];
}
while((i < j) && (arr[i] < temp))
{
i++;
}
if (i < j)
{
arr[j] = arr[i];
}
}
///放入最后的基准
arr[i] = temp;
///左右分别进行快速排序
quick_sort(arr, start, i-1);
quick_sort(arr, i+1, end);
}