• 选择类排序总结


    选择类排序总结

    所谓选择类排序的思想就是:从数组的中选出最大或最小的,通过多次选择最后达到排序的目的

    首先是简单选择排序

    思想:每趟扫描中,选出最小的数字放在最前面,然后从第二个数字开始扫描,直到只剩下最后一个数不需要扫描

    void EasySelect_Sort(int a[],int n)
    {
    	int k;
    	for(int i=1;i<n;i++)
    	{
    		k=i-1;
    		for(int j=i;j<n;j++)
    		{
    			if(a[j]<a[k])
    			{
    				k=j;
    			}
    		}
    		if(k!=(i-1))
    		{
    			int temp=a[i-1];
    			a[i-1]=a[k];
    			a[k]=temp;
    		}
    	}
    }
    

      

    经过分析可以得到,最坏时间复杂度为O(n²),最好时间复杂度为O(n²)

    空间复杂度为O(1);

    简单选择排序是不稳定的!,例如3,3,2

    二.堆排序

    上面的简单选择排序中,一趟只能选出一个最大的,一趟比较完之后第二趟重新开始比较,这样一来,第一趟比较时的结果就浪费了,我们如果能够将他们利用起来的话,可想而知,可以提高不少效率,堆排序就是在这样的情况下提出来的

    堆排序通过维护堆的数据特点,来实现排序,所谓堆,分为大根堆和小根堆,大根堆就是,根节点大于左子结点且根节点大于右子结点(a[i]>=a[2i]&&a[i]>=a[2i+1])

    我们以大根堆为例,分析,堆排序的过程:

    堆排序分为:维护堆,建立堆,堆排序三个过程

    所谓维护堆:

           也就是保持他堆的性质,假设我们现在将原大根堆的根,也就是最大的结点更换为一个比较小的数值,这样,就破坏了 大根堆的性质,维护堆就是此时发挥作用的,维护堆就是要将这样一个已经被破坏的大根堆恢复为大根堆

    void Keep_Sort(int a[],int n,int m)
    {
    	int x=a[n];
    	int k=n;
    	int i=2*k;
    	bool finish=false;
    	while((i<=m)&&(!finish))
    	{
    		if(i<m&&a[i]<a[i+1])
    		{
    			i+=1;	
    		}
    		if(a[i]<x)
    		{
    			finish=true;
    		}
    		else
    		{
    			a[k]=a[i];
    			k=i;
    			i=2*k;	
    		}
    	}
    	a[k]=x;
    }
    

      以上代码就是维护堆的代码,注意第一个if中不要忘了第一个条件!!!防止越界,调试半天才调出错误

    还有就是建立堆了,

    为了建立堆,我们可以从二叉树的第一个非叶子结点开始,倒着不断地维护堆,直到维护到根节点,这样依赖,一个完美的大根堆就建立了

    void Create_Heap(int a[],int n)
    {
    	for(int i=n/2;i>=1;i--)
    	{
    		Keep_Sort(a,i,n);
    	}	
    }
    

      

    第三步就是堆排序了,


    堆排序利用了大根堆的性质,我们不断地取出大根堆的根,然后使出维护堆的神术,直到,堆灯尽油枯,只剩下一个结点,这时候我们的堆排序也完成了,哈哈,有一种,牺牲小堆,完成大排序的错觉

    在实际的排序过程中,我们首先建立一个堆,然后将根节点与最后一个元素互换,这样最后一个元素就是最大的了,然后使出维护堆的大招,不过这时候维护堆就只维护前面n-1个数,最后的一个数(也就是最大数)我们把他踢出堆外,直到堆中只剩下一个元素,那他自然是最小的了,这时候所有元素从小到大排列

    void Heap_Sort(int a[],int n)
    {
    	Create_Heap(a,n);
    	for(int i=n;i>=2;i--)
    	{
    		int temp=a[i];
    		a[i]=a[1];
    		a[1]=temp;
    		Keep_Sort(a,1,i-1);
    	}
    }
    

      

    注意,堆排序的最好时间复杂度和最坏时间复杂度都为O(nlog2(n))

     空间复杂度为O(1)

    堆排序不稳定

    可以看出,选择排序基本上都是不稳定的

    亲爱的听众朋友我是你的代班DJ
  • 相关阅读:
    JDK所有版本
    application.yml配置log日志
    eclipse配置lombok
    Eclipse配置springboot
    java 连接mongodb
    MongoDB shell操作
    mysql插入一万条数据
    Web设计精髓(转)
    SyntaxHighlighter -- 代码高亮插件
    input之placeholder与行高的问题。
  • 原文地址:https://www.cnblogs.com/YTYMblog/p/6103203.html
Copyright © 2020-2023  润新知