排序综合,选择排序,桶排序,插入排序,冒泡排序,归并排序,快速排序 附视频链接

  最近准备备考蓝桥杯,由于一道题,是关于排序问题的,我用了两种方法,我就在想会不会还有其他方法,然后经过总结,就有了下面这些算法,其实这些算法在数据结构中老师都讲过,只是我没有总结与反思,现在就一起做个总结吧

一、选择排序

        选择排序算法是通过遍历数组,选择出数组的最小或最大值,与指定位置交换数据,遍历完整个数组的所有位置就完成了

  视频链接:选择排序_哔哩哔哩_bilibili

//选择排序 选择一个最小的或者最大的,从小到大排序或者从大到小排序
#include <iostream>
using namespace std;
#include <algorithm>
int main()
{
	int arr[] = { 5,6,8,4,2,9,1,3 }; //初始化一个数组
	int len = 8;   //计算数组的长度,方便下面循环

	int k;   //大用 
 
	for (int i = 0; i < 8; i++)
	{
		k = i;               //先把i的值给k
		for (int j = i + 1; j < 8; j++)
		{
			if (arr[k] > arr[j])
				k = j;       //找出最小数的下标,从小到大排序
		}
		if (k != i)
		{
			swap(arr[i], arr[k]);   //如果k的值发生变化了,说明最小值并不是起始的i,现在开始交换两个数
		}
	}
	for (int i = 0; i < 8; i++)
	{
		cout << arr[i] << " ";
	}

	return 0;
}

二、计数排序 也叫做 桶排序

             算法原理是将数组分到有限数量的桶里,再对每个桶分别排好序(可以是递归使用桶排序,也可以是使用其他排序算法将每个桶分别排好序),最后一次将每个桶中排好序的数输出。

        算法详解
    桶排序的思想就是把待排序的数尽量均匀地放到各个桶中,再对各个桶进行局部的排序,最后再按序将各个桶中的数输出,即可得到排好序的数。

   1、  首先确定桶的个数。因为桶排序最好是将数据均匀地分散在各个桶中,那么桶的个数最好是应该根据数据的分散情况来确定。首先找出所有数据中的最大值mx和最小值mn;

根据mx和mn确定每个桶所装的数据的范围 size,有
size = (mx - mn) / n + 1,n为数据的个数,需要保证至少有一个桶,故而需要加个1;

    2、 求得了size即知道了每个桶所装数据的范围,还需要计算出所需的桶的个数cnt,有
cnt = (mx - mn) / size + 1,需要保证每个桶至少要能装1个数,故而需要加个1;

求得了size和cnt后,即可知第一个桶装的数据范围为 [mn, mn + size),第二个桶为 [mn + size, mn + 2 * size),…,以此类推
因此步骤2中需要再扫描一遍数组,将待排序的各个数放进对应的桶中。

    3、 对各个桶中的数据进行排序,可以使用其他的排序算法排序,例如快速排序;也可以递归使用桶排序进行排序;

将各个桶中排好序的数据依次输出,最后得到的数据即为最终有序。

视频链接:计数排序_哔哩哔哩_bilibili

//计数排序(桶排序)
#include <iostream> 
using namespace std;
int a[20];
int main()
{
	int n, score;
	cin >> n;   //定义的数组最大空间是20,根据自己的需要
	for (int i = 1; i <= n; i++)
	{
		cin >> score;   //不同的分数放在不同的桶里
		a[score]++;  //给score这个桶里面的计数加一
	}

	for (int i = 1; i <= 10; i++)   //再把每个桶的数据打印出来
	{
		while (a[i]!=0) //a[i!=0]是指这个桶里有数据,如果没有数据他会i++,开始下一个桶          
		{
			cout << i<<" ";
			a[i]--; //桶里有多个数据,每打印一个数据桶里的数据就少一,还有的话继续while循环
		}
	}
	return 0;
}

三、插入排序

            插入法排序的思路就是将要排序的数组分两个区间,一个是已排序区间,一个是未排序区间。初始时,默认第一个元素是已排序区间的,后面的所有元素为未排序区间。然后依次取未排序区间的元素,在已排序区间找到合适的位置插入,直到排完所有数据。

视频链接:插入排序_哔哩哔哩_bilibili

//插入排序  从第二个元素开始,依次与前面的元素相比较,直到元素排到正确为止即可,每插入一个元素前面的元素已经排好顺序
#include <iostream>
using namespace std;
#include <algorithm>  //swap函数
int main()
{
	int arr[9] = { 2,4,58,6,5,23,8,4,2 };
	int len = 9;
	for(int i=1;i<len;i++)
		for (int j = i; j > 0; j--)
		{
			if (arr[j-1] > arr[j])   //如果后面元素比前面元素大的话,交换数值,这是从小到大排序
				swap(arr[j], arr[j - 1]);
			else
				break;
		}

	for (int i = 0; i < 9; i++)
	{
		cout << arr[i] << " ";
	}

	return 0;
}

四、冒泡排序   也是最经典的排序问题        

        从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。

     以从小到大排序为例,第一轮比较后,所有数中最大的那个数就会浮到最右边;第二轮比较后,所有数中第二大的那个数就会浮到倒数第二个位置……就这样一轮一轮地比较,最后实现从小到大排序。
图像展示

    
 

                  

//冒泡排序   与插入排序相似,插入排序是左边的有序,冒泡是右边的有序;
//插入排序是拿前面无序的与后面有序的比较,而冒泡则与后面无序的比较
#include <iostream>
using namespace std;
#include <algorithm>

int main()
{
	int arr[6] = { 7,6,3,5,4,9 };  //6 3 5 4 7 9

	int len = 6;
	for(int i=0;i<len;i++)                      //一共要循环多少次,几个数就循环几次
		for (int j = 0; j < len - i -1 ; j++)   //每循环一次就排好一个数字,注意是 len-i-1, 
                                                //每次都是第一个元素与后面元素比较
		{
			if (arr[j] > arr[j + 1])   //从小到大排序
				swap(arr[j], arr[j+1]);
		}
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}

	return 0;
}

五、归并排序  这里会用到递归思想

           

该算法将线性表分成若干个块,每个块内的元素可以无序,但块与块之间必须有序。通过在每个块中设置一个索引元素,可以快速定位到目标元素所在的块,然后再在该块内进行查找。

视频链接:归并排序_哔哩哔哩_bilibili

具体的分块查找过程如下:

  1. 将线性表分成若干个块,每个块内的元素可以无序,但块与块之间必须有序。
  2. 在每个块中选择一个索引元素,通常选择每个块的第一个或最后一个元素作为索引元素。
  3. 根据目标元素的值,确定它可能所在的块。
  4. 在确定的块内进行顺序查找,直到找到目标元素或者确定目标元素不存在。
    //归并排序
    #include <iostream>
    using namespace std;
    int arr[8] = { 2,5,6,8,7,5,2,55 };
    int brr[8];   //这里需要另外开辟一个数组用来临时存放
    
    
    void fenkuan_sort(int l, int r)
    {
    	if (l == r) return; 
    	int mid = (l + r) >> 1;  //>>1右移一个单位与 除以二类似,非负数,二者相等,负偶数二者相 
                                 //等,负奇数二者不等
    	fenkuan_sort(l, mid);     //递归
    	fenkuan_sort(mid + 1, r);  //递归
    
    	int i = l, j = mid + 1, k = l;
    	while (i <= mid && j <= r)
    	{
    		if (arr[i] <= arr[j])  //左边与右边相比,从小到大排序,谁的小,谁就放在另一个数组中临时 
                                   //存放  
    		{
    			brr[k] = arr[i];
    				i++;           //存放完之后,得继续下一个元素,++,  
    		}	
    		else
    		{
    			brr[k] = arr[j];   //小的先存放在另一个数组中
    			j++;
    		}
    		k++;
    	}
    	//mid两边的元素都已经排好序了,剩下的元素就可以直接复制过来
    	while (i <= mid) brr[k++] = arr[i++];     //1、brr[k]=arr[i] 2、k+1,i+1
    	while (j <= r) brr[k++] = arr[j++];			1、brr[k]=arr[j] 2、k+1,j+1
    	for (int i = l; i <= r; i++)//已经排序完毕了,现在需要将brr数组的数据放在arr数组中
    	{
    		arr[i] = brr[i];
    	}
    }
    
    int main()
    {
    	int len = 8;
    
    	fenkuan_sort(0, len - 1);
    
    	for (int i = 0; i < len; i++)
    	{
    		cout << arr[i] << " ";
    	}
    
    	return 0;
    }
    

 

 六、快速排序   也会用到递归思想

         

算法解题方法
    1.分解:
    将要解决的问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题。

    2.治理:
    求解各个子问题。由于各个子问题与原问题形式相同,只是规模较小而已,而当子问题划分得足够小时,就可以用简单的方法解决。

    3.合并:
    按原问题的要求,将子问题的解逐层合并构成原问题的解。

视频链接:快速排序_哔哩哔哩_bilibili

//快速查找
#include <iostream>
using namespace std;
#include <algorithm>

int arr[8] = { 5,6,8,1,23,8,7,2 };
void quick_sort(int l, int r)
{
	if (l > r) return;
	int i = l, j = r;
	int base = arr[l];   //将最左侧数据作为参考
	while (i < j)
	{
		注意注意注意
		/*while (i < j && arr[i] <= base) i++;*/   //如果先运行这一行的话,输出结果不对,有顺 
       //序而言
		 while (i<j && arr[j] >= base) j--;   //j在右侧,从右往左

		while (i < j && arr[i] <= base) i++;  //i在左侧,从左往右

		if (i < j)							// //当i等于j的时候,交换数据
			swap(arr[i], arr[j]);     
	}

	swap(arr[l], arr[i]);
	quick_sort(l, j - 1);
	quick_sort(j+1, r);

}


int main()
{

	int len = 8;
	quick_sort(0, len - 1);
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	return 0;
}


 

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值