交换排序算法【冒泡排序,快速排序】C代码

交换排序算法【冒泡排序,快速排序】C代码

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

void arrPrintf(int* data, int length)
{
	for (size_t i = 0; i < length; i++)
	{
		if (i == length - 1)
			printf("%2d\n", data[i]);
		else
			printf("%2d, ", data[i]);
	}

}

//冒泡排序
void bubbleSort(int* data, int length)
{
	int min = 0, index = 0;
	for (size_t i = 0; i < length - 1; i++)
	{
		//注意这里的判断条件
		for (int j = 0; j < length - i -1; j++)
		{
			if (data[j] > data[j+1] )
			{
				//交换位置
				int temp = data[j];
				data[j] = data[j+1];
				data[j+1] = temp;
			}
		}
		printf("第 %2d 次排序 : ", i + 1);
		arrPrintf(data, length);
	}

}

//交换
void swap(int* data, int i, int j)
{
	int temp = data[i];
	data[i] = data[j];
	data[j] = temp;
}



//分区操作
int partSort(int* data, int left, int right)
{
	//最小子问题:区间只有一个值(left==right),或者为空(left>=right)
	if (left >= right) return 0;

	//只有2个值时,若左比右小就直接return0
	if (right - left == 1 && data[left] < data[right]) return 0;

	int end = right;//先从右向左找比key对应元素小的值,找到后暂停
	int begin = left;//然后再从左向右找比key对应元素大的值,找到后暂停,并end与begin进行数据交换,然后再从右开始找
	int key = left;//基准下标

	
	for (int i = left; i <= right; i++)
	{
		if(i == left)
			printf("【 %2d, ", data[i]);
		else if(i == right)
			printf("%2d 】", data[i]);
		else
			printf("%2d, ", data[i]);
	}
	

	while (begin < end)//当左右指针相遇时结束
	{
		//先移动右指针,找比基准小的
		while (data[end] >= data[key] && begin < end)
		{
			end--;
		}

		//再移动左指针,找比基准大的
		while (data[begin] <= data[key] && begin < end)
		{
			begin++;
		}

		//交换数据
		swap(data, begin, end);
	}

	//到这里说明相遇了,将key对应元素与相遇时下标对应元素互换
	swap(data, key, begin);

	key = begin;//基准下标,已经排好序的下标
	return key;
		 
}

//快速排序
void quickSort(int* data, int left, int right,int length)
{
	static int index = 0;
	//只有一个元素时
	if (left >= right) return;

	//霍尔法
	int key = partSort(data, left, right);

	index++;
	printf("第 %2d 次排序 ,基准值 %2d : ", index,data[key]);
	arrPrintf(data, length);

	//递归子区间[left,key -1] key [key+1,right]
	quickSort(data, left, key - 1, length);
	quickSort(data, key + 1, right, length);

}

int main()
{
	//交换排序
	printf("冒泡排序算法\n");

	/*
	稳定:若有2个相等的键值元素,在排序前后它们的相对位置保持不变,比如【2,3,5_a,5_b】(这里5_a,5_b为值相同的元素)
		  在排序后5_a依然在5_b前面,则相对位置保持;否则称为不稳定
	归位:比较过就可以确定元素的位置

	冒泡排序:稳定,归位

	思路:
	1.比较相邻的两个元素,如果第一个比第二个大就交换
	2.一趟下来后,最大的元素就在最后面
	3.依次类推,直到排序完毕

	*/
	int data[] = { 2,5,29,15,39,98,41,3,55,55,20,78,18,88 };
	arrPrintf(data, sizeof(data) / sizeof(data[0]));
	printf("排序前后--数据长度:%d\n", sizeof(data) / sizeof(data[0]));
	bubbleSort(data, sizeof(data) / sizeof(data[0]));
	arrPrintf(data, sizeof(data) / sizeof(data[0]));
	/*
	冒泡排序算法
					 2,  5, 29, 15, 39, 98, 41,  3, 55, 55, 20, 78, 18, 88
	排序前后--14
	第  1 次排序 :  2,  5, 15, 29, 39, 41,  3, 55, 55, 20, 78, 18, 88, 98
	第  2 次排序 :  2,  5, 15, 29, 39,  3, 41, 55, 20, 55, 18, 78, 88, 98
	第  3 次排序 :  2,  5, 15, 29,  3, 39, 41, 20, 55, 18, 55, 78, 88, 98
	第  4 次排序 :  2,  5, 15,  3, 29, 39, 20, 41, 18, 55, 55, 78, 88, 98
	第  5 次排序 :  2,  5,  3, 15, 29, 20, 39, 18, 41, 55, 55, 78, 88, 98
	第  6 次排序 :  2,  3,  5, 15, 20, 29, 18, 39, 41, 55, 55, 78, 88, 98
	第  7 次排序 :  2,  3,  5, 15, 20, 18, 29, 39, 41, 55, 55, 78, 88, 98
	第  8 次排序 :  2,  3,  5, 15, 18, 20, 29, 39, 41, 55, 55, 78, 88, 98
	第  9 次排序 :  2,  3,  5, 15, 18, 20, 29, 39, 41, 55, 55, 78, 88, 98
	第 10 次排序 :  2,  3,  5, 15, 18, 20, 29, 39, 41, 55, 55, 78, 88, 98
	第 11 次排序 :  2,  3,  5, 15, 18, 20, 29, 39, 41, 55, 55, 78, 88, 98	
	第 12 次排序 :  2,  3,  5, 15, 18, 20, 29, 39, 41, 55, 55, 78, 88, 98
	第 13 次排序 :  2,  3,  5, 15, 18, 20, 29, 39, 41, 55, 55, 78, 88, 98
	*/

	/*
	快速排序:
	1.从数列中挑出一个元素(一般为头或尾元素),称为“基准”pivot
	2.排列数列,所有元素比基准值小的排在基准值前面,所有比基准值大的元素排在基准值后面
	  基准值处于中间位置,这个称为分区(partition)操作。
	  具体操作例子:假设取基准为头元素,有2个指针,左指针指向数列头,右指针指向数列尾,
	  右指针向左先移动,当右指针遇到比基准小的元素停下来;左指针向右移动,当左指针碰到
	  比基准大的元素就停下,此时左右指针交换元素,右左指针继续移动,直到左右指针碰到
	  一块了,将指针指向的元素与基准交换。到此完成了一轮的遍历,并且可以得到2个子序列。
	3.递归的进行子序列的排序。


	快速排序:不稳定,归位

	*/
	printf("快速排序算法\n");
	//int data1[] = { 22,5,29,15,39,98,41,3,55,55,20,78,18,88,1,99,50 };
	int data1[] = { 22,5,29,15,39,98,41,3,55 };
	int length1 = sizeof(data1) / sizeof(data1[0]);
	printf("第 %2d 次排序 : ", 0);
	arrPrintf(data1, length1);
	quickSort(data1, 0, length1 - 1, length1);
	arrPrintf(data1, length1);
	/*
	快速排序算法
											第  0 次排序 : 22,  5, 29, 15, 39, 98, 41,  3, 55
	【 22,  5, 29, 15, 39, 98, 41,  3, 55 】第  1 次排序 ,基准值 22 : 15,  5,  3, 22, 39, 98, 41, 29, 55
	【 15,  5,  3 】						第  2 次排序 ,基准值 15 :  3,  5, 15, 22, 39, 98, 41, 29, 55
											第  3 次排序 ,基准值  3 :  3,  5, 15, 22, 39, 98, 41, 29, 55
	【 39, 98, 41, 29, 55 】				第  4 次排序 ,基准值 39 :  3,  5, 15, 22, 29, 39, 41, 98, 55
	【 41, 98, 55 】						第  5 次排序 ,基准值 41 :  3,  5, 15, 22, 29, 39, 41, 98, 55
	【 98, 55 】							第  6 次排序 ,基准值 98 :  3,  5, 15, 22, 29, 39, 41, 55, 98
	*/


	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值