❥十大排序算法❥爆肝两万字保姆级教程(文字解析+图解+代码实现+例题)

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以上是关于❥十大排序算法❥爆肝两万字保姆级教程(文字解析+图解+代码实现+例题)的主要内容,如果未能解决你的问题,请参考以下文章

保姆级教程HTML两万字笔记大总结建议收藏(上篇)

保姆级教程CSS两万字笔记大总结建议收藏(上篇)

❤️通宵爆肝两万字xpath教程+实战练习❤️

10W+字C语言从入门到精通保姆级教程(2021版下)

《爆肝整理》保姆级系列教程-玩转Charles抓包神器教程(15)-Charles如何配置反向代理

Java 基础语法爆肝两万字解析 Java 的多态抽象类和接口