❥十大排序算法❥爆肝两万字保姆级教程(文字解析+图解+代码实现+例题)
Posted 静Yu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❥十大排序算法❥爆肝两万字保姆级教程(文字解析+图解+代码实现+例题)相关的知识,希望对你有一定的参考价值。
适合新人的入门级文章
什么是算法?
平时学计算机的小伙伴经常会听到算法这个词,那到底什么是算法呢?
算法并没有一个明确的定义,依我个人理解算法就是求解特定问题对解题思路和步骤的描述。
其实网上有很多十大算法的文章,各位大佬们写的都非常不错,大佬们水平很高,所以写的文章也是比较深的,我个人是个新人。写的这篇文章也特别适合刚入门学习的新人,简单入手。
十大排序算法
🎈冒泡排序
解析
冒泡排序是一种最基础的交换排序,就好比是我们平时喝的可乐,从底部一直冒到顶部。具体实现方法就是根据数的大小一点一点的往一侧移动,如果按照从小到大的顺序就将小的数从右边一直往左挪。
举例:将3.2.5.8.1这五个数从小到大排序
1.第一步,从右面开始比较,将小的数往左挪,1先和8比较,1小所以和8互换位置。
2.第二步,1再和5比较,还是1较小和5互换位置。
3.同理,直到全部比较之后,1最小在第一个位置
4.然后重新开始比较,8比5大所以不用挪动,然后2和5比较,5大不用移动,2再和3比较,2小和3互换位置,2再和1比较不用移动,再从右往左比较一遍,没有可以移动的最终结果为1.2.3.5.8
代码实现
function bubbleSort(arr) {
var len = arr.length;
for (var i = 0; i < len - 1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j+1]) { // 相邻元素两两对比
var temp = arr[j+1]; // 元素交换
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
例题
本题目用到的就是冒泡排序,如果前一个数比后一个数大的话ans就加1
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n+1],ans;
ans=0;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
if(a[i]<a[j])
ans++;
printf("%d",ans);
}
🎈选择排序
解析
选择排序顾名思义是从所有的元素中选择一个最小(大)的,放在序列的起始位置,然后再从剩余队列中,选择一个最小(大)的,放在第二个位置。
举例:将3.2.5.8.1这五个数从小到大排序
1.第一步:首先从所有队列中选出最小的那个数,最小的是1,然后放到序列首位
2.第二步:再从剩下的四个数中找到最小的那个,放到第二个位置,最小的是2
3.第三步:同理,依次排序下去,最终为
代码实现
function selectionSort(arr) {
var len = arr.length;
var minIndex, temp;
for (var i = 0; i < len - 1; i++) {
minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) { // 寻找最小的数
minIndex = j; // 将最小数的索引保存
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
例题
本人感觉此题就是为选择排序“量身定做”,第一个数选最大的,第二个数选最小的,第三个数是从剩下的数中选最大的。
#include<iostream>
using namespace std;
int main(){
int n=0;
long int a[1000]={0};
cin>>n;
for(int i=0; i<n; i++) cin>>a[i];
for(int i=0; i<n-1; i++) {
int min_index = i;
for(int j=i; j<n; j++) if(a[j] > a[min_index]) min_index = j;//找出第 i 小的数所在的位置
swap(a[i],a[min_index]);//将第 i 小的数,放在第 i 个位置;如果刚好,就不用交换
i++;
for(int j=i; j<n; j++) if(a[j] < a[min_index]) min_index = j;//找出第 i 小的数所在的位置
swap(a[i],a[min_index]);//将第 i 小的数,放在第 i 个位置;如果刚好,就不用交换
}
for(int i=0; i<n; i++) cout<<a[i]<<endl;
}
🎈插入排序
解析
插入排序的思想是分为有序序列和无序序列,将无序序列中的数插入到有序序列中,直到所有的数全部插入。
举例:将3.2.5.8.1这五个数从小到大排序
1.第一步:3为有序序列,2.5.8.1为无序序列,
2.将无序序列的第一个数拿出来插入到有序序列
3.然后将无序序列的5插入有序序列
4.同理
5.最终结果为
代码实现
function insertionSort(arr) {
var len = arr.length;
var preIndex, current;
for (var i = 1; i < len; i++) {
preIndex = i - 1;
current = arr[i];
while (preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1] = current;
}
return arr;
}
例题
题目描述
清华附小期末考试结束后,分别由数学、语文、英语按照学号顺序输入30名同学的成绩,班主任想知道三门课总分的最高分和最低分,以及取得总分最高分和最低分的两位同学的编号。(输入数据保证没有同分情况,编号由1到30)
输入描述
第一行输入编号为1-30的30位同学的数学成绩,分数之间用空格隔开;第二行输入语文成绩,第三行输入英语成绩
输出描述
输出四个数,分别是总分最高分,总分最低分,取得最高分同学的编号,取得最低分同学的编号
#include <iostream>
#include <stdlib.h>
using namespace std;
int main() {
int*math = new int[3];
int*chinese = new int[3];
int*english = new int[3];
for (int n = 0; n < 3; n++) {
cin >> math[n];
}
for (int n = 0; n < 3; n++) {
cin >> chinese[n];
}
for (int n = 0; n < 3; n++) {
cin >> english[n];
}
int*sum= new int[3];
int*order = new int[3];
for (int n = 0; n < 3; n++) {
sum[n] = math[n] + chinese[n] + english[n];
}
for (int n = 0; n <= 2; n++) {
order[n] = sum[n];
}
for (int n = 1; n <=2; n++){
int now = sum[n], space = 0;
while (now > sum[space])
space++;
for (int i = n; i > space; i--)
sum[i] = sum[i - 1];
sum[space] = now;
}
int max, min;
for (int n = 0; n <= 2; n++) {
if (order[2] == sum[n])
max = n;
if (order[0] == sum[n])
min = n;
}
cout << sum[2] << endl;
cout << sum[0] << endl;
cout << max<<endl;
cout << min<<endl;
system("pause");
return 0;
}
🎈希尔排序
解析
希尔排序主要思想是将数据进行分组,然后对每一组数据进行插入排序,在每一组数据都有序后,再对所有的分组利用插入排序进行最后一次排序。可以说是对插入排序的升级版,通过减少数据交换的次数,以达到加快排序的速度。
举例:将3.2.5.8.1.6这六个数从小到大排序
1.第一步:分组依据为两个一组,六个数分为三组,第一个和第四个一组,第二个和第五个一组,第三个和第六个一组。
2.第二步:3和8相比,2和1相比,5和6相比,小的排前大的排后
3.第三步:然后再分成3/2=1组,直接所有的数据插入排序
代码实现
function shellSort(arr) {
var len = arr.length;
for (var gap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) {
// 注意:这里和动图演示的不一样,动图是分组执行,实际操作是多个分组交替执行
for (var i = gap; i < len; i++) {
var j = i;
var current = arr[i];
while (j - gap >= 0 && current < arr[j - gap]) {
arr[j] = arr[j - gap];
j = j - gap;
}
arr[j] = current;
}
}
return arr;
}
例题
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
int n,k,i,a[100001],b[100001],ans=0;
scanf("%d%d",&n,&k);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);//sort从小到大排序
for(i=1;i<=n-1;i++)
b[i]=a[i+1]-a[i];//算出各等级选手的差
sort(b+1,b+n);//sort从小到大排序
for(i=1;i<=k;i++)
ans+=b[i];//找出前K个等级差的和
printf("%d",ans);//输出
return 0;
}
🎈归并排序
解析
归并排序主要思想是对整个序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的。
举例:将3.2.5.8.1.6这六个数从小到大排序
1.第一步:首先是逐层折半分组,两个一组一共分成三组。
2.第二步:然后是每组进行排序
3.第三步:然后再逐层合并,按照从小到大。
4.第四步:在进行排序合并
这里插入个动图便于大家理解
代码实现
function mergeSort(arr) {
var len = arr.length;
if (len < 2) {
return arr;
}
var middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
var result = [];
while (left.length>0 && right.length>0) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length)
result.push(left.shift());
while (right.length)
result.push(right.shift());
return result;
}
例题
#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
string s;
map<string,int>nmsl;
int n;
long long ans=0;
int c[1000001],d[1000001];
void qsort(int a,int b)
{
if(a==b)return;
int mid=(a+b)>>1;
int i=a,j=mid+1,k=a;
qsort(a,mid),qsort(mid+1,b);
while(i<=mid&&j<=b)
if(c[i]<=c[j])
{
d[k++]=c[i++];
}
else
{
d[k++]=c[j++];
ans+=mid-i+1;
}
while(i<=mid)
d[k++]=c[i++];
while(j<=b)
d[k++]=c[j++];
for(int l=a;l<=b;l++)
c[l]=d[l];
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>s;
nmsl[s]=i;
}
int j=0;
for(int i=1以上是关于❥十大排序算法❥爆肝两万字保姆级教程(文字解析+图解+代码实现+例题)的主要内容,如果未能解决你的问题,请参考以下文章