【C】排序算法之冒泡排序

1、算法基本思想

以升序为例:

a.比较相邻的两个数字,若前者大于后者,则交换两个数字的顺序,反之则不交换;(ps:交换两个数字的顺序)

b.重复上述操作,直到最大的数字“沉”入最右边,最小的数字“浮”在最左边为止。

假如有 N 个数字排序,那么需要比较 N-1 趟,在每一趟的比较中,比较次数有所不同,第 i 趟比较需要比较 N-1-i 次。

2、源代码

a.整型数字排序

/*
*	函数名称:BubbleSort
*
*	函数功能:冒泡排序(升序)方法1
*
*	入口参数:a, len
*
*	出口参数:无
*
*	返回类型:void
*/

void BubbleSort(int * a, int len)
{
	int i = 0;
	int j = 0;

	assert(NULL != a);

	for (i=0; i a[j+1]) {
				a[j] = a[j] ^ a[j+1];
				a[j+1] = a[j] ^ a[j+1];
				a[j] = a[j] ^ a[j+1];
			}
		}
	}

	return;
}

不足:即使所给数字是有序的,上述算法仍会对其进行一趟又一趟的比较,这样效率太低。

改进:考虑设置一个标志位,假如在某一趟比较中没有发生任何数字的交换,那么说明此刻已经是一个有序的序列,不需要再进行比较了。

首先设置一个标志位 flag = 1,每次进入循环后先把 flag 置 0,假如发生了数字交换,再把 flag 置 1,最后判断 flag 的值,假如为 0 则结束循环。

/*
*	函数名称:BubbleSort
*
*	函数功能:冒泡排序(升序)方法2
*
*	入口参数:a, len
*
*	出口参数:无
*
*	返回类型:void
*/

void BubbleSort(int * a, int len)
{
	int i = 0;
	int j = 0;
	int flag = 1;

	assert(NULL != a);

	while (flag) {
		flag = 0;

		for (i=0; i a[j+1]) {
					a[j] = a[j] ^ a[j+1];
					a[j+1] = a[j] ^ a[j+1];
					a[j] = a[j] ^ a[j+1];
					flag = 1;
				}
			}
		}

		if (0 == flag)
			break;
	}

	return;
}

不足:代码繁琐,多次判断 flag 。

改进:考虑在外层循环中同时判断 flag 以及外层循环变量。

/*
*	函数名称:BubbleSort
*
*	函数功能:冒泡排序(升序)方法3
*
*	入口参数:a, len
*
*	出口参数:无
*
*	返回类型:void
*/

void BubbleSort(int * a, int len)
{
	int i = 0;
	int j = 0;
	int flag = 1;

	assert(NULL != a);

	for (i=0; (i a[j+1]) {
				a[j] = a[j] ^ a[j+1];
				a[j+1] = a[j] ^ a[j+1];
				a[j] = a[j] ^ a[j+1];
				flag = 1;
			}
		}
	}

	return;
}

当然,也可以使用指针来实现冒泡排序。

/*
*	函数名称:BubbleSort
*
*	函数功能:冒泡排序(升序)方法4 (指针实现)
*
*	入口参数:pArr, len
*
*	出口参数:无
*
*	返回类型:void
*/

void BubbleSort(int * pArr, int len)
{
	int * left = pArr;
	int * right = pArr + len - 1;
	int * current = pArr;
	int flag = 1;

	assert(NULL != pArr);

	for (left=pArr; (left *(current+1)) {
				*current = (*current) ^ (*(current+1));
				*(current+1) = (*current) ^ (*(current+1));
				*current = (*current) ^ (*(current+1));
				flag = 1;
			}
		}
	}

	return;
}

输入输出函数及主函数

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:BubbleSort.c
* 功能:冒泡排序算法实现(升序)
*
*/

# include 
# include 
# include 

# define ARRAY_LEN 4

/*
*	函数名称:Input
*
*	函数功能:输入数据
*
*	入口参数:pNum, length
*
*	出口参数:无
*
*	返回类型:void
*/

void Input(int * pNum, int length)
{
	int k = 0;

	if ((NULL != pNum) && (length > 0)) {
		for (k=0; k 0)) {
        for (m=0; m

b.字符串排序

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:StringBubbleSort.c
* 功能:冒泡排序之排序多个字符串
*
*/

# include 
# include 
# include 

/*
*	函数名称:StringBubbleSort
*
*	函数功能:多个字符串冒泡排序(升序)
*
*	入口参数:str, len
*
*	出口参数:void
*
*	返回类型:void
*/

void StringBubbleSort(char * *str, int len)
{
    int i = 0;
    int flag = 1;

    assert((NULL != str));

    for (i=0; (i 0) {
                char * tmp = str[j];
                str[j] = str[j+1];
                str[j+1] = tmp;
                flag = 1;
            }
        }
    }

    return;
}

/*
*	函数名称:OutputStr
*
*	函数功能:输出字符串
*
*	入口参数:str, len
*
*	出口参数:void
*
*	返回类型:void
*/

void OutputStr(char * *str, int len)
{
    int i = 0;
    assert((NULL != str));
    for (i=0; i

c.通用冒泡排序

/*
*	函数名称:Swap
*
*	函数功能:交换内容
*
*	入口参数:s1, s2, width
*
*	出口参数:void
*
*	返回类型:void
*/

void Swap(char * s1, char * s2, int width)
{
	int i = 0;

	assert((NULL != s1) && (NULL != s2));

	for(i=0; i 0) {
				Swap((char *)base + width * j, (char *)base + width * (j+1), width);
			}
		}
	}

	return;
}

接下来以排序结构体中的姓名为例,

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:CommonBubbleSort.c
* 功能:不区分数据类型的冒泡排序
*       void qsort( void *base, size_t num, size_t width, 
*       int (__cdecl *compare)(const void *elem1, const void *elem2) );
*
*/

# include 
# include 
# include 

struct Student
{
	char name[20];
	int age;
};

/*
*	函数名称:CmpStructName
*
*	函数功能:比较结构体中的姓名
*
*	入口参数:e1, e2
*
*	出口参数:大于0 or 小于0 or 等于0
*
*	返回类型:int
*/

int CmpStructName(const void * e1, const void * e2)
{
	assert((NULL != e1) && (NULL != e2));

	return strcmp(((struct Student *)e1)->name, ((struct Student *)e2)->name);
}

/*
*	函数名称:PrintStructData
*
*	函数功能:打印结构体内容
*
*	入口参数:stu, len
*
*	出口参数:void
*
*	返回类型:void
*/

void PrintStructData(struct Student stu[], int len)
{
	int i = 0;

	for (i=0; i

3、输出结果

a.整型数字排序

【C】排序算法之冒泡排序_第1张图片

【C】排序算法之冒泡排序_第2张图片

b.字符串排序

c.通用冒泡排序

【C】排序算法之冒泡排序_第3张图片

你可能感兴趣的:(C编程练习,排序算法,七大排序算法解析)