交换排序算法【冒泡排序,快速排序】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;
}