算法——冒泡排序,选择排序,直接插入排序,希尔排序(源代码讲解)

1.冒泡排序

冒泡排序是指数组中的数两两比较,满足条件的两个数进行排序操作,而非从第一位比较到最后一位;

C

#include<stdio.h>
int main()
{
    
    
	int a[10]={
    
    5,6,8,2,4,1,9,3,7};//初始化一个乱序数组 
	for(int i=0;i<8;i++)
	{
    
    
		for(int j=0;j<9-i-1;j++)//每次比较a【i】之后数组种的数 
		{
    
    
			if(a[j]>a[j+1])//如果a[j]>a[j+1] ,交换这两个位置上的数,使小的在前大的在后 
			{
    
    
				int t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	for(int i=0;i<9;i++)//输出冒泡排序后的数组 
	printf("%d ",a[i]);
	return 0;
}

冒泡排序的核心部分是双重嵌套循环,时间复杂度为O(N^2)

2.选择排序

选择排序是从第一个数开始,和数组之后的每一个数进行比较,找出最大的或最小的进行交换,交换完成后从下一个数开始再次进行比较,第一次比较n次,第二次比较n-1次,依次递减

C

#include<stdio.h>
int main()
{
    
    
	int i = 0;         //定义一个i并且赋初值为0,i作为数组的下标
	int j = 0;      //定义j并且赋初值为0,j作为找到最大值时所对应的下标
	int k;            //定义一个k,用来保存此次循环中最大值的下标
	int temp;         //定义一个中间变量temp,供以后交换值的时候使用
	int a[]={
    
    4,2,5,6,8,1,7,9,3,0};    //定义了一个9个数的数组,并且初始化
	int len = sizeof(a)/sizeof(a[0]);  //len是数组的大小
	for(i = 0;i<len;i++)        //判断i是否小于len,执行下面的语句
	{
    
    
		k = i;           //假设此次循环中的最大值就是当前的值   
		for(j = i+1;j<len;j++)
		{
    
    
			if(a[j]>a[k])    //将假设的当前最大值与后面的值比较
			{
    
    
				k = j;     //若后面的值更大,则交换下标
			}
		}//当前最大值
		if(k != i)       //比较之后如果此次循环中最大值并非当前值
		{
    
     
			temp = a[i];   //将此次循环中的最大值与a[k]交换
			a[i] = a[k];
			a[k] = temp;
		}
	}
	for(i=0;i<len;i++)       //利用for循环将结果依次输出
	{
    
    
		printf("%d ",a[i]);
	}
	return 0;
}

C++

#include<iostream>
using namespace std;
int main()
{
    
    
	int i = 0;         //定义一个i并且赋初值为0,i作为数组的下标
	int j = 0;      //定义j并且赋初值为0,j作为找到最大值时所对应的下标
	int k;            //定义一个k,用来保存此次循环中最大值的下标
	int temp;         //定义一个中间变量temp,供以后交换值的时候使用
	int a[]={
    
    4,2,5,6,8,1,7,9,3,0};    //定义了一个9个数的数组,并且初始化
	//int len = sizeof(a)/sizeof(a[0]);  //len是数组的大小
	int len=a.size();
	for(i = 0;i<len;i++)        //判断i是否小于len,执行下面的语句
	{
    
    
		k = i;           //假设此次循环中的最大值就是当前的值   
		for(j = i+1;j<len;j++)
		{
    
    
			if(a[j]>a[k])    //将假设的当前最大值与后面的值比较
			{
    
    
				k = j;     //若后面的值更大,则交换下标
			}
		}//当前最大值
		if(k != i)       //比较之后如果此次循环中最大值并非当前值
		{
    
     
			temp = a[i];   //将此次循环中的最大值与a[k]交换
			a[i] = a[k];
			a[k] = temp;
		}
	}
	for(i=0;i<len;i++)       //利用for循环将结果依次输出
	{
    
    
		cout<<a[i]<<" ";
	}
	return 0;
}

3.直接插入排序

一个数组若是要按照从小到大的顺序排序,若第 i 项小于他的前一项或前几项,就将第 i 项插入所有比它大的数之前

#include<iostream>
using namespace std;
int main()
{
    
    
	int i=0,j=0;
	int k;
	int temp;
	int a[]={
    
    5,1,9,6,4,8,2,3,7,0};
	int len=sizeof(a)/sizeof(a[1]);//数组长度 
	for(i=1;i<len;i++)
	{
    
    
		if(a[i-1]>a[i])//如果后项比前项小,将这一项插入比它大的数之前 
		{
    
    
			temp=a[i];
			for(j=i-1;j>=0&&a[j]>temp;j--)
			{
    
    
				a[j+1]=a[j];//将j以及之后的数向后移一位 
			}
			a[j+1]=temp;//j+1是for循环机制哦,不懂的重开 
		}
		
	}
		for(i=0;i<len;i++)
			cout<<a[i]<<" ";
	return 0; 
}

4.希尔排序

我们不难发现,以上三种排序的时间复杂度都为O(n^2)
而希尔排序的时间复杂度只有n*logn,所以希尔排序的效率要高出以上三种排序方法很多,
~~

希尔排序是特殊的插入排序,直接插入排序每次插入前的遍历步长为1,而希尔排序我们可以设置一个初始增量gap,每次排序gap/=2;我们就可以实现一个时间复杂度为n*logn的特殊的插入排序(希尔排序

希尔排序是将待排序列分为若干个子序列,对这些子序列分别进行直接插入排序,当每个子序列长度为1时,再进行一次直接插入排序时,结果一定是有序的。常见的划分子序列的方法有:初始步长(两个子序列相应元素相差的距离)为要排的数的一半,之后每执行一次步长折半。

#include<iostream>
using namespace std;
int main()
{
    
    
	int i=0,j=0;
	int k;
	int temp;
	int a[]={
    
    5,1,9,6,4,8,2,3,7,0};
	int len=sizeof(a)/sizeof(a[1]);//数组长度 
	int gap=len/2;//初始定义希尔排序的分段增量为数组的一半 
	while(gap)
	{
    
    
		for(i=0;i<len;i++)
		{
    
    
			for(j=i+gap;j<len;j+=gap)//增量为gap,每次比较i和i+gap项的值 
			{
    
    
				if(a[i]>a[j])
				{
    
    
					temp=a[i];
					a[i]=a[j];
					a[j]=temp;
				}
			}
		}
		gap=gap/2;//结束时增量减少一半,进行下一次排序 
	}
		for(i=0;i<len;i++)
			cout<<a[i]<<" ";
	return 0; 
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_59708493/article/details/120897313