基于C++实现 冒泡排序 选择排序 折半查找

前言

这是一个C++排序算法帖,会发一些自己学的排序算法,以及对它们的理解。

一、冒泡排序

优缺点:
优点:比较简单,空间复杂度较低,是稳定的
缺点:时间复杂度太高,效率不好

1,原理解释

本例以排序int arr[10]={8,3,55,7,5,4,17,21,2,10};为例,且按升序排序,数据在定义时给出。

冒泡排序的原理是,一个数从底下向上,如果下一个数比这个数大,就交换他们的值,保存大的值继续向上,这样最后的位置就变为了,这些数的最大数。

就像是水里的气泡,从底下不断向上升,最后升到水面。(私以为这就是冒泡排序的名字由来)

2,代码演示

#include <iostream>
using namespace std;
 /*冒泡排序*/
int main()
{
	int arr[10]={8,3,55,7,5,4,17,21,2,10};
	int temp;//定义中间值
	for(int i=0;i<9;i++) {//外层for控制输出了几个排序好的数
		for(int j=0;j<9-i;j++){//内层for控制寻找这个排序的数
							  //每次完成一次内层for的循环,最上面就排好了一个数,所以不用循环到9个数,循环到9-i即可		
			if(arr[j]>arr[j+1]){//如果这个数大于下一个数,就交换它两的值
				temp=arr[j];//存下将要交换数的值
				arr[j]=arr[j+1];//交换这个值
				arr[j+1]=temp;//现在,后一个数就是这俩个数的大值
			}
				
		}
	}
	for(int i=0;i<10;i++){//打印冒泡排序后的结果
		cout<<arr[i]<<" ";
	}

    return 0;
}

结果演示:
在这里插入图片描述
关于为什么定义一个中间值temp:
假设我们定义了a,b。想要交换他们的值
int a=3,b=5;
我们直接赋值:
a=b;
b=a;
是无法达到交换两值的目的的,因为第二赋值值时,a的值已经被换成5了.

所以我们要定义一个中间值,先存下要被换的值。
int a=3,b=5,temp;
temp=a;
a=b;
b=temp;
这样就达到了交换的目的.

二、选择排序

优点:移动数据的次数已知(n-1 次 ),用着简单;
缺点:比较次数多。

1,原理解释

本例以排序int arr[10]={8,3,55,7,5,4,17,21,2,10};为例,且按升序排序,数据在定义时给出。

选择排序就是从第一个数开始,比较后面的所有数,如果后面的数有小于这个数的,就将他们交换。比较完一次所有的数后就找到了其中最小的一个数,放在最前面。
所以需要两层for循环,外层for控制现在是第几个数,内层for控制这个数和其后所有数比较.

2,代码实现

#include <iostream>
using namespace std;
 /*选择排序*/
int main()
{
	int arr[10]={8,3,55,7,5,4,17,21,2,10};
	for(int i=0;i<9;i++){//内层for会比较其后一个数,所以循环到9就可以了
		for(int j=i+1;j<10;j++){//比较这个数和后面的所有数,所以要比较到9+1
			if(arr[i]>arr[j]) {//如果这个数大于后面的数,就交换他们的值
				int temp;//定义一个中间值
				temp=arr[i];//存下被交换的值 
				arr[i]=arr[j];//交换这个值
				arr[j]=temp; //现在它们已经交换完毕了
				
			}
		}
	} 
	for(int i=0;i<10;i++){//打印排好顺序的数组
		cout<<arr[i]<<" ";
	}
    return 0;
}

结果演示:
在这里插入图片描述

三、折半查找

1,原理解释

本例以输入一个10长的数组int arr[10]={1,5,6,8,9,12,15,17,18,20};
输入一个数num,查找num在这个数组的位置。

原理:为查找位置的数组设置左右边界,左边界m,右边界n,比较两者中间的数arr[(m+n)/2],看num是在中间数的左边还是右边,移动边界,循环执行,直到找到这个数。该数是边界的数时为特殊情况,要提前判断。

简而言之就是在一半的左边还是右边,一半的一半的左边还是右边,一半的一半的一半。。。继续这样来查找

2,代码实现

本例是以输入一个数num查找该数在数组int arr[10]={1,5,6,8,9,12,15,17,18,20};中的位置

代码:

#include<iostream>
#include<string>
using namespace std;
/*
折半查找 

输入一个数,查找它是这个10长数组的第几个元素 
*/


int main() {
		int arr[10]={1,5,6,8,9,12,15,17,18,20} ;
		int m=0,n=9;//左边界:m,右边界:n 
		int num;//需要查找的数
		cin>>num;//输入这个数 
		for(;;){
		 	if (num>20||num<1){ //如果这个数不在该数列中,退出循环,输出错误 
		 		cout<<"输入错误"<<endl;
				 break; 
			}
			if(num==arr[m]){	//当这个数是左边界时 
				cout<<"这个数在位置:"<<m<<endl;
				break;
			}
			if(num==arr[n]){//当这个数是右边界时 
				cout<<"这个数在位置:"<<n<<endl;
				break;
			}
			if(num<arr[(m+n)/2]){  //中间数大于这个数,移动右边界数到它们中间的位置,也就是位置:(m+n)/2 
				n=(m+n)/2;	
			}
			else if(num>arr[(m+n)/2]){//中间数小于输入数时,移动左边界 
				m=(m+n)/2;
			}
			else {
				cout<<"这个数在位置"<<(m+n)/2; //当中间数不大于,不小于输入数时,输入数就是现在这个中间数,输出该位置 
				break;
			}
		
			
		} 
		
		
		return 0;
}

代码运行结果:
输入12,找出该数在arr数组的5位置
在这里插入图片描述

后言

这是一个C++实现排序算法的算法贴,会持续更新,以供自己学习和他人参考之用。 欢迎大家评论和指出错误,以及建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值