选择排序和插入排序及其优化

选择排序(固定位置,找元素)

基本思想:对于长度为N的无序数列,第一次遍历,将第0个元素和后边所有元素相比较,找出最小的元素,然后和第0个元素交换,第二遍历,将第1个元素和后边所有的元素比较,找出剩下元素中最小的元素,然后和第1个元素交换,重复以上步骤直至最后一次遍历只剩下两个元素的时候,排序完成。

时间复杂度:O(n*n)

空间复杂度:O(1)

是否是稳定排序:不是稳定排序

代码示例:(根据上面的算法思想不难写出下面的代码)

 

#include <stdio.h>
#include <stdlib.h>

#defind ARRAY_LEN(x) (sizeof(x)/sizeof((x)[0]))

int exchange_times = 0;
int compare_times = 0;

int Swap(int *a, int *b)
{
	int c;
	int ret = -1;
	
	ret = (a != NULL)&&(b != NULL);
	
	if(ret)
	{
		c = *a;
		*a = *b;
		*b = c;
	}
	
	return ret;
}

int SelectSort1(int a[], int n)
{
	int ret = -1;
	int i = 0, j = 0;
		
	ret = (a != NULL)&&(n > 0);
	
	if(ret)
	{
		//外层循环最多进行n-1次 
		for(i = 0; i < n - 1; i++)
		{			
			for(j = i + 1; j < n; j++)
			{
				if(a[j] < a[i])
				{
					Swap(&a[i],&a[j]);
					exchange_times++;					
				}
				compare_times++;
			}	
		}
	}
	
	return ret; 
}


int PlayFunc(int *a, int n)
{
	int i = 0;
	int ret = -1;
	
	ret = (a != NULL)&&(n > 0);
	
	if(ret)
	{
		printf("Array[]:");
		for(i = 0; i < n; i++)
			printf("%d, ", a[i]);
		printf("\n");
	}
	
	return ret;
}

void main()
{
	int array[] = {8,5,10,7,6,9,4,3,2,1};

    PlayFunc(array, ARRAY_LEN(array));
	
	SelectSort1(array, ARRAY_LEN(array));
	
	PlayFunc(array, ARRAY_LEN(array));
	
	printf("exchange_times: %d\n", exchange_times);
	printf("compare_times: %d\n", compare_times);
}

 

 

运行效果截图:


 

 

 

上面的选择排序一样可以优化,每次只做比较,记录下无序序列中最小元素的下标,即每次遍历最多交换一次。下面贴上代码:

 

int SelectSort2(int a[], int n)
{
	int ret = -1;
	int i = 0, j = 0;
	
	int MinIndex = 0;
	
	ret = (a != NULL)&&(n > 0);
	
	if(ret)
	{
		//外层循环最多进行n-1次 
		for(i = 0; i < n - 1; i++)
		{
			MinIndex = i;		
			for(j = i + 1; j < n; j++)
			{
				if(a[j] < a[MinIndex])
				{
					MinIndex = j;//找出并记录最小值下标 
				}
				compare_times++;
			}
			
			if(i != MinIndex)
			{
				Swap(&a[i],&a[MinIndex]);
				exchange_times++;
			}
		}
	}
	
	return ret; 
}


运行效果截图:(和上面优化前相比,元素交换次数大大减少)

 

算法是不是很神奇!!!

 

 

 

插入排序(固定元素,找位置)

基本思想:对于长度为N的无序数列,需要进行N-1次插入排序。第一次,数列中第0个数认为是有序的数列,将数列中第1个元素插入仅有1个有序的数列中,第二次,数列的前两个元素已经成了有序数列,继续将第2个元素插入到前面两个元素的有序序列中,直到第N-1次,将数组中第N-1(最后一个)个元素插入前面的有序序列中,插入排序完成。

时间复杂度:O(n*n)

空间复杂度:O(1)

是否是稳定排序:稳定排序

代码示例:

 

#include <stdio.h>
#include <stdlib.h>

#define SIZE 10

int exchange_times = 0;
int compare_times = 0;

int Swap(int *a, int *b)
{
	int c;
	int ret = -1;
	
	ret = (a != NULL)&&(b != NULL);
	
	if(ret)
	{
		c = *a;
		*a = *b;
		*b = c;
	}
	
	return ret;
}

int InsertSort1(int a[], int n)
{
	int ret = -1;
	int i = 0, j = 0;
	int Temp = 0;
		
	ret = (a != NULL)&&(n > 0);
	
	if(ret)
	{
		for(i = 1; i < n; i++)
		{
			if(a[i-1] > a[i])//从小到大排列  0到i-1是已经排好的有序序列 
			{
				Temp = a[i];
				
				for(j = i - 1; (j >= 0) && (Temp < a[j]) ; j--)//边比较边挪数据 
				{
					a[j+1] = a[j];
					exchange_times++;
					//compare_times++; 
				}
				
				a[j+1] = Temp;//将数据插入恰当的位置 
				compare_times++; 
			}
		}
	}
	
	return ret; 
}



int PlayFunc(int *a, int n)
{
	int i = 0;
	int ret = -1;
	
	ret = (a != NULL)&&(n > 0);
	
	if(ret)
	{
		printf("Array[]:");
		for(i = 0; i < n; i++)
			printf("%d, ", a[i]);
		printf("\n");
	}
	
	return ret;
}

void main()
{
	int array[SIZE] = {8,5,10,7,6,9,4,3,2,1};

	PlayFunc(array, 10);
	
	InsertSort1(array, 10);
		
	PlayFunc(array, 10);
	
	printf("exchange_times: %d\n", exchange_times);
	printf("compare_times: %d\n", compare_times);
}


运行效果截图:

 

此处的交换次数和比较次数不能说明什么,这个算是简单的插入排序吧。同样算法还可以继续优化...未完待续!!!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值