交换排序 (冒泡排序和快速排序)

冒泡排序:

用2层for循环实现,i代表的是趟数,j代表的是每趟比较的次数,每趟冒出i之后最小的数。

void bubble(int arr[], int len)
{
	int i = 0, j = 0;
	for (i = 0; i < len - 1; i++)
	{
		int count = 0; //是否进行交换的标记
		for (j = 0; j < len - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				count = 1;
			}
		}
		if (count == 0) //如果某一趟遍历完后没有进行数的交换,
			            //说明此组数已经有序,则直接跳出循环
		{ 
			break;
		}
	}
}

快速排序:

1、双指针法

 (a):基准值位置变动

int doublePointerWay1(int * src, int start, int end)
{
	int a = start, b = end;
	int flag = 1;
	while (src[a] < src[b])
	{
		b--;
	}
	while (a < b)
	{
		swap(src + b, src + a);
		flag = !flag;
		while (src[b] >= src[a])
		{
			flag ? a++ : b--;
		}
	}
	return flag ? b : a;
}
void dealQuickSort(int * src, int start, int end)
{
	int mid;
	if (start < end)
	{
		mid = doublePointerWay1(src, start, end);
		dealQuickSort(src, start, mid-1);
		dealQuickSort(src, mid + 1, end);
	}
}
void QuickSort(int *src, int n)
{
	dealQuickSort(src, 0, n - 1);
}

(b):保护基准值法

int doublePointerWay2(int * src, int start, int end)
{
	int a = start;
	int b = end - 1;
	int mid = (start + end) / 2;
	swap(src + mid, src + end);
	while (a <= b)
	{
		while (a < end && src[a] <= src[end])
		{
			a++;
		}
		while (b > 0 && src[b] >= src[end])
		{
			b--;
		}
		if (a == b && (a == 0 || a == end))
		{
			break;
		}
		if (a < b)
		{
			swap(src + a, src + b);
		}
	}
	swap(src + end, src + a);
	return a;
}
void dealQuickSort(int * src, int start, int end)
{
	int mid;
	if (start < end)
	{
		mid = doublePointerWay2(src, start, end);
		dealQuickSort(src, start, mid-1);
		dealQuickSort(src, mid + 1, end);
	}
}
void QuickSort(int *src, int n)
{
	dealQuickSort(src, 0, n - 1);
}

2、入坑法

(a).定义a和b分别指向第一个元素和最后一个元素,基准值tmp为数第一个元素,src[start]元素的位置为一个坑

(b).b从后往前走,找比tmp小的值,找到之后,将src[b]赋值给src[a],填充a位置的坑,此时b位置为一个新的坑

(c).a从前往后走,找比tmp大的值,找到之后,将src[a]赋值给src[b],填充b位置的坑,此时a位置为一个坑

(d).重复步骤(b)(c),当a和b相遇,则循环结束,将tmp的值填最后一个坑。
 

int digWay(int *src, int start, int end)
{
	int a = start;
	int b = end;
	int tmp = src[start];
	while (1)
	{
		while (b > 0 && src[b] >= tmp)
		{
			b--;
		}
		if (a < b)
		{
			src[a] = src[b];
		}
		else
		{
			src[a] = tmp;
			return a;
		}
		while (a < end && src[a] <= tmp)
		{
			a++;
		}
		if (a < b)
		{
			src[b] = src[a];
		}
		else
		{
			src[b] = tmp;
			return b;
		}
	}
}
void dealQuickSort(int * src, int start, int end)
{
	int mid;
	if (start < end)
	{
		mid = digWay(src, start, end);
		dealQuickSort(src, start, mid-1);
		dealQuickSort(src, mid + 1, end);
	}
}
void QuickSort(int *src, int n)
{
	dealQuickSort(src, 0, n - 1);
}

3、三数取中法 (hoare)

取前中后三个数,对3个数进行排序,取中间的数为基准值。除去两头的数对其余数用双指针法中的保护基准值法进行排序。

int HoareWay(int *src, int start, int end)
{
	int a = start + 1;
	int b = end - 2;
	int mid = (start + end) / 2;
	if (src[start] >= src[mid])
	{
		swap(src + start, src + mid);
	}
	if (src[mid] >= src[end])
	{
		swap(src + mid, src + end);
	}
	if (src[start] > src[mid])
	{
		swap(src + start, src + mid);
	}
	if (end - start <= 2)
	{
		return mid;
	}
	swap(src + mid, src + end - 1);
	while (a <= b)
	{
		while (a < end - 1 && src[a] <= src[end - 1])
		{
			a++;
		}
		while (b > 1 && src[b] >= src[end - 1])
		{
			b--;
		}
		if (a == b && (a == 1 || a == (end - 1)))
		{
			break;
		}
		if (a < b)
		{
			swap(src + a, src + b);
		}
	}
	swap(src + end - 1, src + a);
	return a;

}
void dealQuickSort(int * src, int start, int end)
{
	int mid;
	if (start < end)
	{
		mid = HoareWay(src, start, end);
		dealQuickSort(src, start, mid-1);
		dealQuickSort(src, mid + 1, end);
	}
}
void QuickSort(int *src, int n)
{
	dealQuickSort(src, 0, n - 1);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值