排序算法的C语言实现以及各个算法的时间复杂度和空间复杂度分析(冒泡排序)

  排序算法是一种很重要的算法,在各个方面都有很多应用,下面用C语言实现一下各个排序算法,并总结一下各种排序算法的时间复杂度和空间复杂度。要总结的排序算法为:

冒泡排序、简单选择排序、直接插入排序、希尔排序、堆排序、归并排序、快速排序。

(1)冒泡排序(最简单的初级版本):

假设我们有一个整型数组,数组里面的数的排位是随机的,要对他们进行升序排列。排序的思想如下:数组的第一个数和其他数依次进行比较,将较小的放在第一位,然后第二个数依次和它后面的数进行比较,较小的数放在第二位,然后是第三个数、、、、、最后到倒数第二个数和最后一个数进行比较,进行最后的排序,那么算法结束之后整个数组就是升序排列的数组了。

代码如下:

	void BuSortedPrim(int Array[ ], int k)
	{
		int i ;
		int j;
		int tmp;
		for( i = 0; i <=k - 2; ++i)
			for(j = i + 1; j <= k-1; ++j)
			{
				if(Array[j] < Array[i])
				{
					tmp = Array[i];
					Array[i] = Array[j];
					Array[j] = tmp;
				}
			}
	}

改进的冒泡排序:

思路如下:从最后一个数开始,依次与前面的数比较,将较小的数交换到前面,

代码如下:

	void BuSorted( int Array[ ], int k)
	{
		int i ;
		int j;
		int tmp;
		for(i = 0; i <= k-2; ++i)
			for(j = k-1; j>= i + 1; --j)
			{
				if(Array[j] < Array[j -1])
				{
					tmp = Array[j];
					Array[j] = Array[j -1];
					Array[j -1] = tmp;
				}
			}
	}

可以看到,在这个算法中,较小的数不断上升,这个算法的效率高于初级的版本,这个才是正宗的冒泡算法。

冒泡算法还可以进行改进,比如在排序进行到某一次,当我们已经知道数组已经排好,这个时候就不必要再从最后一位往上依次进行比较了,这样会大大提高算法的效率。

如何实现呢,具体的做法是这样的,设置一个标记,每次进行比较之前将标记的值设置为0,然后开始从最后一位依次与前面的数进行比较。如果发生了交换则标记变为1,当标记为1的时候让程序判断这个时候发生了比较,则进行下一次比较;如果没有发生比较,标记依然是0,当前的比较结束的时候程序根据这个零判断此时整个数组已经是有序的,则可以结束循环,算法结束。

代码如下:

	void BuSortedImpr(int Array[], int k)
	{
		int i ;
		int j;
		int tmp;
		int flag = 1;
		for( i = 0; i <=k-2&&1 == flag; ++i)
		{
			flag = 0;
			for(j = k -1; j >=i+1; --j)
			{
				if(Array[j] < Array[j-1])
				{
					flag = 1;
					tmp = Array[j];
					Array[j] = Array[j -1];
					Array[j - 1] = tmp;
				}
			}
	}

对冒泡算法的时间复杂度和空间复杂度进行分析,很明显,算法在运行时,需要的辅助空间很小,只需要两个用来遍历数组的常数i、j,然后需要一个用于交换的临时存储空间tmp,再加一个判断是否需要继续执行算法的变量flag,所以空间复杂度是常量。

再来看看时间复杂度,在最后的情况下,也就是数组已经是升序的情况下,只需要遍历一次(BuSortedImpr),此时的时间复杂度为0(n);在最坏情况下,整个数组是降序排列的,这个时候每一次都需要进行交换,时间复杂度为n(n-1)/2,时间复杂度为0(n^2)。

 


你可能感兴趣的:(算法)