插入法(直接/二分/希尔)

文章讨论了双向冒泡排序、插入排序(包括直接插入和二分插入法)以及希尔排序的实现,强调了在不同规模数据下的时间效率对比,尤其关注于小规模数据的快速定位和性能优化。
摘要由CSDN通过智能技术生成
//稳定耗时: 双向冒泡,可指定最大最小值个数MaxMinNum<n=sizeof(Arr)/sizeof(Arr[0]),
void BiBubbleSort(int Arr[],int n,int MaxMinNum){
    int left=0,right=n-1;
    int i;
    bool notDone= true;
    int temp;
    int  minPos;
    while(left<right&&notDone  ){        
        notDone= false;
        for(i=left;i<right;i++){
            if(Arr[i]>Arr[i+1]){

                
                //swap(Arr[i],Arr[i+1]);
                temp=Arr[i];
                Arr[i]=Arr[i+1];
                Arr[i+1]=temp;

                
                notDone= true;//
            }
             // if(Arr[i]<Arr[left])//minPos=i; //最小值
			//	{
			//		  temp=Arr[left];
           	//		  Arr[left]=Arr[minPos];
	        // 		  Arr[minPos]=temp;
			//	}
            
        }
        right--;//右边界增加一个最大值
 
        for(i=right-1;i>=left;i--){
            if(Arr[i]>Arr[i+1]){
                //swap(Arr[i],Arr[i+1]);
                temp=Arr[i];
                Arr[i]=Arr[i+1];
                Arr[i+1]=temp;
                notDone= true;
            }
         }
        left++;//左边界增加一个最小值
         if(MaxMinNum>0){MaxMinNum--;if(MaxMinNum==0)return;}
    }
}

直接插入

void InsertSort(int* arr, int n)
{
	for (int i = 0; i < n - 1; ++i)
	{
		int end = i;//记录有序序列最后一个元素的下标
		int tem = arr[end + 1];//待插入的元素
		//单趟排
		while (end >= 0)
		{
			//比插入的数大就向后移
			if (tem < arr[end])
			{
				arr[end + 1] = arr[end];
				end--;
			}
			//比插入的数小,跳出循环
			else
			{
				break;
			}
		}
		//tem放到比插入的数小的数的后面
		arr[end  + 1] = tem;
		//代码执行到此位置有两种情况:
		//1.待插入元素找到应插入位置(break跳出循环到此)
		//2.待插入元素比当前有序序列中的所有元素都小(while循环结束后到此)
	}
}
 

二分插入法直接插入上改进(n<1024),明显减少数据比较次数,快速定位,n过大不如直接插入快;

a[] 有序:type为 0 时排序从小到大,为 1 时排序从大到小,n=sizeof(a)/sizeof(a[0]);
void InsertSort_binary(int a[],int n)//,int type)
{
    for ( int i = 1; i < n; i++)
    {
        int temp=a[i];  //临时待插入值
        int left=0;  //左侧边界值
        int right=i-1;  //右侧边界值
        while (left <= right)
        {
           // int mid = (left+right) / 2;  //中间值 可能溢出INT_MAX;
             int mid = left + ( right - left) / 2;
            if(a[mid] > temp)//if(type == 0 ? (a[mid] > temp) : (a[mid] < temp))
            {
                right = mid - 1;   //把右侧边界缩小,在中间值得左边进行寻找
            }
            else 
            {
                left = mid + 1;  //把左侧边界加大,在中间值得右边进行寻找
            }            
        }
        for ( int j = i-1; j >= left; j--)  //将left到i-1之间的数都往后移动一个位置
        //如果j<left 或j=0,将不会有数进行位置的移动
        {
            a[j+1] = a[j];
        }
        a[left] = temp;      //将要插入的数值插入到合适位置       
    }    
}

希尔 非稳定排序,最高效接近快排;

void ShellSort(int* arr, int size)
{
    int gap = size;
    while (gap > 1)
    {
        gap = gap / 3 + 1;	//调整希尔增量
        int i = 0;
        for (i = 0; i < size - gap; i++)	//从0遍历到size-gap-1
        {
            int end = i;
            int temp = arr[end + gap];
            while (end >= 0)
            {
                if (arr[end] > temp)
                {
                    arr[end + gap] = arr[end];
                    end -= gap;
                }
                else
                {
                    break;
                }
            }
            arr[end + gap] = temp;	//以 end+gap 作为插入位置
        }
    }
}

n=10000 时间对比

n=100000 时间对比

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值