1、本栏用来记录社招找工作过程中的内容,包括基础知识学习以及面试问题的记录等,以便于后续个人回顾学习; 暂时只有2023年3月份,第一次社招找工作的过程;
2、个人经历: 研究生期间课题是SLAM在无人机上的应用,有接触SLAM、Linux、ROS、C/C++、DJI OSDK等;
3、参加工作后(2021-2023年)岗位是嵌入式软件开发,主要是服务器开发,Linux、C/C++、网络编程、docker容器、CMake、makefile、Shell脚本、JSON等。4、求职岗位是嵌入式软件开发、C/C++开发、自动驾驶岗位开发等。
本节将记录排序算法部分的学习。
关于排序算法详细的介绍,以及动图演示等,详见
http://t.csdn.cn/voGYo
https://blog.csdn.net/weixin_63449996/article/details/126980331
这里只记录一下这几种排序算法的C语言实现。
void InsertSort(int* a, int n)
{
for (int i = 0; i < n-1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + 1] = a[end];
end--;
}
else
{
break;//找到正确顺序的插入位置
}
}
a[end + 1] = tmp;
}
}
选择排序,即每次从待排序的序列中选出一个最小值,然后放在序列的起始位置begin(排好一个元素之后,begin递增),直到全部待排序数据排序完成。
比如有十个数,第一次找出前十个中最小的数,放在a[0];第二次找出除第一个外剩余9个中的最小值,放在a[1];第三次找除第一第二个外,剩余8个中的最小值,放在a[2];以此类推。
void SelectSort(int* a, int n)
{
//先假设第一个元素最小
for (int i = 0; i < n; i++)
{
int begin = i;
int minindex = i;
while (begin < n)
{
if (a[begin] < a[minindex])
{
minindex = begin;
}
begin++;
}
Swap(&a[minindex], &a[i]);
}
}
选择排序的优化版本:
实际上,我们可以一趟选出两个值,一个最大值,一个最小值,然后将最小值放在开头,最大值放在末尾,然后left++
,right–
,依次继续在剩下的数据当中找最大值和最小值,这样可以使选择排序的效率快一倍。
void SelectSort2(int* a, int n)
{
int left = 0;
int right = n - 1;
while (left < right)
{
int minindex = left;
int maxindex = left;
for (int i = left; i <= right; i++)
{
if (a[i] < a[minindex])
{
minindex = i;
}
if (a[i] > a[maxindex])
{
maxindex = i;
}
}
Swap(&a[minindex], &a[left]);
if (maxindex == left)
{
maxindex = minindex;
}
Swap(&a[maxindex], &a[right]);
left++;
right--;
}
}
冒泡排序是一种交换排序,冒泡排序是从第一个元素开始,相邻的两个数俩俩比较,若后面一个数大于前一个数则交换,一直到把每趟的最大元素都排在末尾,所以冒泡排序是比较函数的一种。根据动图来观察,冒泡排序算法跟直接选择排序有点像,排好的元素,相对的位置之间就不再变动了。
void bubble_Sort(int* a, int n)
{
int i = 0;
int j = 0;
int flag = 0;
for (i = 0; i < n - 1; i++)//趟数
{
for (j = 0; j < n - 1 - i; j++)//相邻元素之间的比较次数
{
if (a[j + 1] < a[j])
{
Swap(&a[j], &a[j + 1]);
flag = 1;
}
}
if (flag == 0)
{
break;
}
}
}
快速排序是公认的排序之王,快速排序是Hoare在1962年提出的一种二叉树结构的排序算法,他是一种交换排序,基本思想为:
任取待排序元素中的某元素作为基准值key,按照该基准值将带排序序列分为两个子序列,左边子序列的值都小于基准值,右边则都大于基准值,然后左右序列重复该过程(递归),直到所有元素都排列在相遇的位置上为止。
思路:
1、选出一个key,一般是最左边或是最右边的。
2、定义一个begin和一个end,begin从左向右走,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;
//选左边为key
int 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[keyi+1,right]
QuickSort(arr, left, keyi - 1);
QuickSort(arr,keyi + 1,right);
}