如果你已经学会C,C++(或看过《C++Primer》)的基本语法,想要再精进一层的话,那就是该接触数据结构与算法的时候了,这个系列博文的主题亦如此,所提供的代码都是在学习这些的过程中,自己写的代码,且亲测有效。
无数前辈说过,程序 = 数据结构 + 算法,数据结构就是内存对数据的存储方式,算法就是对数据的加工处理。那么对于超大量的数据,为了管理他们,为了以后好取出想要的值,对他们的加工处理基本上都是按照各种排序方式,排来排去。
《Effictive C++》赞美之音传于四海,这本书的中文翻译者侯捷,他老人家更是桃李满天下。他第一次听人说了电脑就是对存进来的数据排一下序,很难相信,他认为因为电脑是一种顶级高科技的存在,是用来发射火箭的,怎么就只排排数据。所以很容易忽略排序的重要性,因为我们平时都是处理的小量数据,想取哪一个数据手动,输出一下就行了。
举个业务上的例子,现在各个银行都在建设5G银行,系统会保存客户的人脸图片,当客户下次去银行的时候,门口会有声音欢迎王先生光临~。因为门口会有摄像头做人脸拍照,然后与数据库的照片比对排序。这种比对是一个个比吗,如果客户在上亿的量,一个个比太慢了,系统的实现是按照图片上的特性值,把之前在数据库中存的上亿照片按照一定的方式排序,这样就不需要一个个比对,可以用二分查找这类方法快速找到。
排序算法,分两部分,业务 + 代码,业务即是算法怎么实现这个功能的,文字上描述一下,代码是具体是实现。无论上个小系列数据结构还是接下来的算法,我都将采用这种方式讲解。理解业务更易看懂代码,然有些业务说起来很抽象,照猫画虎的不好文字描述,直接看代码范围理解快一点,所以两者可以结合着来理解。
刚开始学前几个排序时,这些排序是最简单的也是最难的,最简单是因为学了好久之后再回来看,最难是因为刚刚接触的前几个排序,一看晕了,再看排序算法这么多,放弃了。其实不然,只要学会几个,后面就会很轻松,还有助于你以更高的视野看前面学过的算法。
并归排序又提供了一种排序的新思路,而不是包含或改进其他算法。思路:
若数组中的元素按左小右大排序,首选把这些这些数组分成两组,每组再分成两组,直至成为单个元素。然后对最左边两个单个元素排序,排后把这两个元素放在临时的数组里。然后将这个临时空间跟这两个元素跟第三个元素排序,定义两个下边变量,指向临时空间的数组第一个,另一个指向第三个元素,然后将指向的两个元素比大小。小的放在新开辟的临时数组中,然后放进去的那个数组,指针向右移一位,没放进去的不移动,重复刚才的动作。直到有一个数组放进去完,把没比完的全放进去。之后拿这个数组跟其他已经按照此方式排好的临时数组再按照此方式排序,最终整个数组有序。具体看代码实现。
郭襄:我走过山时,山不说话,我路过海时,海不说话。
很多时候,这个世界是自己的跟他人无关,生活需要自己去探索。
上代码,亲测有效!
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <time.h>
#include <sys/timeb.h>
using namespace std;
#define MAX 10
//创建随机数组
int* CreateArray()
{
srand((unsigned int)time(NULL));
int* arr = (int*)malloc(sizeof(int) * MAX);
for (int i = 0; i < MAX; i++)
{
arr[i] = rand() % MAX;
}
return arr;
}
//打印
void PrintArray(int arr[], int len)
{
for (int i = 0; i < len; i++)
{
cout << arr[i] << "";
}
cout << endl;
}
//合并算法 从小到大
void Merge(int arr[], int start, int end, int mid, int* temp)
{
int i_start = start;
int i_end = mid;
int j_start = mid + 1;
int j_end = end;
//表示辅助空间有多少个元素
int length = 0;
//合并两个有序序列
while (i_start <= i_end && j_start <= j_end)
{
if (arr[i_start] < arr[j_start])
{
temp[length] = arr[i_start];
length++;
i_start++;
}
else
{
temp[length] = arr[j_start];
j_start++;
length++;
}
}
//两个序列比较后,其中一个序列可能还有
//剩余元素没有复制到赋值空间
//i序列
while (i_start <= i_end)
{
temp[length] = arr[i_start];
i_start++;
length++;
}
//j序列
while (j_start <= j_end)
{
temp[length] = arr[j_start];
length++;
j_start++;
}
//辅助空间中的数据复制到原空间
for (int i = 0; i < length; i++)
{
arr[start + i] = temp[i];
}
}
//归并排序
void MergeSort(int arr[], int start, int end, int* temp)
{
if (start >= end)
{
return;
}
int mid = (start + end) / 2;
//分组
//左半边
MergeSort(arr, start, mid, temp);
//右半边
MergeSort(arr, mid + 1, end, temp);
//合并
Merge(arr, start, end, mid, temp);
}
int main(void)
{
int* myArr = CreateArray();
PrintArray(myArr, MAX);
int* temp = (int*)malloc(sizeof(int) * MAX);
MergeSort(myArr, 0, MAX - 1, temp);
PrintArray(myArr, MAX);
//释放空间
free(temp);
free(myArr);
system("pause");
return 0;
}