交换排序与冒泡排序

   今天在读公司的平台代码的时候发现了一处排序的地方,令我意外的是居然还在用最原始的时间复杂度为的   O(n的平方)  排序方式。

刚看到那些代码无法分清究竟是     交换排序    还是    冒泡排序,记得有一次面试的时候让写冒泡排序呢结果写成交换排序了,当时怎么想也想不起来惭愧,

回来后看了一眼才恍然大悟。其实这两个都是课堂上学过的。这里有必要再分析下它们的区别:


首先说冒泡排序:

   将被排序的记录数组R[1..n]垂直排列,每个记录 R[i] 看作是 重量 为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫数组R:

凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下(所谓   清者为天 浊者为地 )为止

code示例如下:(从小到大)

void BubbleSort(int *vInt, size_t size )
{
        int temp;
        size_t i,j;
        for (i = 0; i < size; i++)
        {
                for (j = size - 1; j > i; j--)
                {
                        if (vInt[j] < vInt[j-1])
                        {
                                temp = vInt[j-1];
                                vInt[j-1] = vInt[j];
                                vInt[j] = temp;
                        }
                }
        }
}



然后就是交换排序:

交换法的程序最清晰简单,每次用当前的元素一一的同其后的元素比较并交换。  (从小到大)

void ExchangeSort(int* pData,size_t Count)
{
        int iTemp;
        size_t i,j;

        for(i=0;i<Count-1;i++)
        {
                for(j=i+1;j<Count;j++)
                {
                        if(pData[j]<pData[i])
                        {
                                iTemp = pData[i];
                                pData[i] = pData[j];
                                pData[j] = iTemp;
                        }
                }
        }
}



上面的两种排序可以用如下验证:

int main(void)
{
        int i;
        int array[] = {12,18,81,-14,-1,0,33,38,46};
        int len = sizeof(array)/sizeof(int);

        printf("len is %d\n",len);

        for(i = 0;i< len;i ++)
                printf("%d ",array[i]);
        printf("\n");

        BubbleSort(array,len);

        for(i = 0;i < len; i ++)
                printf("%d ",array[i]);
        printf("\n\n");

        return 0;
}

其实严格来说冒泡排序也属于交换排序的一种,它们的时间复杂度都是   O(n的平方) 。它们的不同点:

冒泡排序在     内部的一个循环   比较连续的2个元素,如果不等则交换。

交换排序是     在内部的一个循环中把每个元素跟外部循环的元素相比较        ,如果不等则交换。




代码优化

	int i = 0;
	SKY_SERVICE_INFO *pServiceInfo[MAX_TOTAL_PROGRAM_NUM] = {NULL};

	for (i = 0; i < iProgramTotal; i++)
	{
		pServiceInfo[i] = sk_mem_malloc(sizeof(SKY_SERVICE_INFO));
		memset(pServiceInfo[i], 0, sizeof(SKY_SERVICE_INFO));
		sky_DM_Service_Get(channel[i], pServiceInfo[i]);
	}
	if (tpye == SORT_SERVICE_ID)
	{
		sk_char_service_id(pServiceInfo, iProgramTotal);

		for (i = 0; i < iProgramTotal; i++)
		{
			channel[i] = pServiceInfo[i]->id;
		}

		SendMessage(hWndGrid[PROGRAL_LIST_GRID], LMSG_SETCONTROLDATA, 0, iProgramTotal);
	}

	for (i = 0; i < iProgramTotal; i++)
	{
		if (pServiceInfo[i] != NULL)
		{
			sk_mem_free(pServiceInfo[i]);
			pServiceInfo[i] = NULL;
		}
	}
上面代码的目的是把指针数组(一个数组,数组的每个元素是指向  SKY_SERVICE_INFO 结构体类型的指针)pServiceInfo 所指向的结构体 按照结构体某个成员来排列,

最后 pServiceInfo 是无用的,有用的仅仅是channel数组(pServiceInfo 通过一定规则排序之后ID与channel对应)

再看下  sk_char_service_id 函数

void sk_char_service_id(SKY_SERVICE_INFO *service_info[], int n)//沉底法则
{
	int i = 0, j = 0, iFlag = 0;
	SKY_SERVICE_INFO tmpe_service_info = {0};

	for (i = 0; i < n - 1; i++)
	{
		iFlag = 1;
		memset(&tmpe_service_info, 0, sizeof(SKY_SERVICE_INFO));
		for (j = 0; j < n - i - 1; j++)
		{
			if (str_order_service_id(service_info[j]->svid, service_info[j+1]->svid) == 0)
			{
				memcpy(&tmpe_service_info, service_info[j], sizeof(SKY_SERVICE_INFO));
				memcpy(service_info[j], service_info[j+1], sizeof(SKY_SERVICE_INFO));
				memcpy(service_info[j+1], &tmpe_service_info, sizeof(SKY_SERVICE_INFO));
				iFlag = 0;
			}
		}

		if (1 == iFlag)
		{			
			break;
		}
	}
}
这里用的只是简单的冒泡排序,而且if里面的交换也有很大优化空间

3次 memcpy 的过程仅仅是让指针      service_info[j]    和指针    service_info[j+1] 指向的内容一致,这3次memcpy可能需要大量的cpu周期,如果采用别的办法,

比如说交换     service_info[j]     和    service_info[j+1]     的指针值那么则可以大大减少cpu周期,采用这种方式之后 sk_char_service_id 函数如下所示:

void sk_char_service_id(SKY_SERVICE_INFO *service_info[], int n)//沉底法则
{
	int i = 0, j = 0, iFlag = 0;
	SKY_SERVICE_INFO *ptmp_service_info = NULL;

	for (i = 0; i < n - 1; i++)
	{
		iFlag = 1;
		for (j = 0; j < n - i - 1; j++)
		{
			if (str_order_service_id(service_info[j]->svid, service_info[j+1]->svid) == 0)
			{
				ptmp_service_info	= service_info[j];
				service_info[j]		= service_info[j+1];
				service_info[j+1]	= ptmp_service_info;
				iFlag = 0;
			}
		}
		if (1 == iFlag)
		{			
			break;
		}
	}
}



另外还有优化的余地,那就是把排序方式改成快速排序。

















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值