目录
冒泡排序
1.将所有相邻的2个元素做比较,小的在前面(上浮)大的排在后面(下沉)。这样比完就把最大的留在了后面。
2.再将最后面那个元素排除,重复上面的操作;
简单来说,冒泡排序就是比较两个两个比较大小,小的在前大的在后,一轮后本轮最大的在最后,在进行下一轮,第二大的就被排在后面了;
代码:
#include<stdio.h>
int main()
{
int arr[5] = { 11,18,9,5,3 };//定义一个数组
int i, j, temp;
printf("排序前:\n");//遍历排序前的数组
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
for (i = 0; i < 5; i++)//外层循环,即执行的轮数
{
for (j = 0; j < 4 - i; j++)//内层循环,每轮执行次数
{
if (arr[j] > arr[j + 1])//后比前小,则交换前后的值
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
printf("\n排序后:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
结果:
图解
第一轮(执行4次):
第一次,序号0和1比较,位置不变。
第二次1和2比较9<18交换位置;
第三次 序号2和3比较,5<18,交换位置。
第四次 3和4比较3<18,交换位置。
第二轮(执行3次)序号4不参与比较
- 0和1比较9<11,交换位置。
- 序号1和2比较5<11,交换位置。
- 序号2和3比较,3<11,交换位置。
第三轮(比较2次),3、4不参与
第一次,0和1比较,9<5,交换位置
第二次 1和2比较,9<3,交换位置。
第四轮,比较一次,5<3交换位置。
冒泡排序结束。冒泡排序一共进行4+3+2+1=10次;
优缺点
优点:简单,空间复杂度较低,稳定
缺点:时间复杂度高O(n²)
选择排序
1.假设序号0的元素为最小元素,将序号0的元素与其它元素对比,
2.遇到比序号0对应的元素还小的元素则进行交换。
3.一轮比较完毕,进行下一轮,此时以序号1的元素为最小元素重复以上步骤;
选择排序就是,选出最小的放在最前面;因为每轮都会选出一个最小元素排在前面,所以从前向后的元素依次增大;选择排序不止可以将最小的放最前面也可以将最大元素排在最后面不过这就类似于冒泡排序了;
代码
#include<stdio.h>
int main()
{
int arr[5] = { 11,18,9,5,3 };
int i, j,temp,m=0;
printf("排序前:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
for (i = 0; i < 5; i++)//外层循环,轮数
{
for (j = i; j < 4; j++)//内层循环,次数,此时让最小值为arr[i]
{
if (arr[i] > arr[j+1])//如果存在比arr[i]还小的值则交换值,
{
temp=arr[i];//j是i的复制体,如果改为j在则i不会发生变化,值也就没有变化
arr[i] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
printf("\n排序后:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
结果
图解
第一轮(4次)
第一次,序号0和1比较,11<18,位置不变,
第二次 0和2比较,11>9交换位置;
第三次 0和3比较9>5,交换位置
第四次 0和4比较,5>3,交换位置
第二轮(3次),序号0不参与比较
第一次 1和2比较16>11,交换位置
第二次 1和3比较,11>9,交换位置
第三次 1和4比较,9>5,交换位置
第三轮(2次),序号0和1不参与比较
第一次 2和3比较18>11,交换位置
第二次 2和4比较,11>9,交换位置
第四轮(1次) 3和4比较18>11,交换位置
选择排序完毕;选择排序一共进行4+3+2+1=10次;
优缺点:
优点:执行效率较冒泡排序高
缺点:效率慢,不稳定,
插入排序
将待排序的数组元素从右向左依次插入已排序数组中;
- 选择序号0的元素作为已排序的元素。
- 将下一个待排序元素(序号1)从右向左插入已排序的数组里,插入方式:本待排序元素比已排序元素大则插入后面小则插入前面。
- 继续取待排序元素重复以上操作;
插入排序在遇到插入前面的情况要继续跟前面的元素进行比较,遇到插入后面的元素便要停止比较;因为待插入的元素比排序好的元素大则一定比它前面的所有元素大,但比待排序元素小不能确定跟前面元素的关系。
代码
#include<stdio.h>
int main()
{
int arr[5] = { 11,18,9,5,3 };
int i, j,temp;
printf("排序前:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
for (i = 1; i < 5; i++)//把arr[0]当做了已排序的元素
{
temp = arr[i];//将待排序的这个元素赋予temp
for(j=i-1;j>=0&&arr[j]>temp;j--)//判断,这个元素(arr[i])的前一位(arr[i-1])是否大于这个元素
{
arr[j+1] = arr[j];//如果大于就将arr[j]的值给arr[j+1],j是新数组的序号
}
arr[j+1] = temp;//将arr[i]插入合适位置
}
printf("\n排序后:\n");
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
结果
图解
第一次 将序号0的元素作为已排序元素放入已排序数组
第二次 将待排序的序号1元素与已排序0比较,18>11,插入0后边。
- 将待排序2的元素与1比较9<18,插入已排序1前面;将待排序2再与已排序0对比9<11,将2插入0前面;
第四次,将待排序序号3的元素和已排序序号2的元素比较,5<18,插入前面,待排序3再与1对比5<11插入前面,再与0对比5<9插入前面;
第五次,待排序4与已排序元素一一对比遇到插入后面的则插入停止比较,遇到插入前面的继续比较,直到最左边为止;
选择排序完毕。共5次;
优缺点
优点:稳定,快
缺点:比较次数不一定,比较次数越多,插入点后的数据移动越多,不适合大规模数据排序
杂谈
写完这篇文章也算是让自己对排序算法有了更深的理解,当然我的理解比较浅薄,就当是学习过程的一个总结。
写下这篇文章也是希望能给初学C语言的同学们一些可以借鉴的东西吧。
说实话,现在大一的我真的还是挺迷惘的,越学越觉得c语言知识的广阔,有时真的就觉得自己学不好,这么多又要怎么学,除了C语言还有java,Python等等都要学的该怎么规划.........有时候就是挺迷惘,现在就只是以考研为目标但大一备考又被说没什么用.....
以上只是我的一些心里话,实际上我还是觉得要走一步看一步,学一点是一点。迷惘的时候就去学会儿,尽量让自己不去想。