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

本文详细介绍了四种常见的排序算法:冒泡排序、选择排序、直接插入排序和希尔排序。每种排序算法通过C语言实现,并附有示例代码。冒泡排序通过相邻元素比较交换实现排序;选择排序每次找到最大或最小元素与当前位置交换;直接插入排序则是将元素插入到已排序部分的正确位置;希尔排序通过设置增量的插入排序提高效率,最后达到整体排序的目的。这四种排序算法在时间和空间复杂度上有所不同,希尔排序效率较高。
摘要由CSDN通过智能技术生成

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; 
}

在这里插入图片描述

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒野大飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值