DSAA 第一章 引论

练习(p12)
1.1

/*
*	date:		2016-01-14 
*	question:	编写一个程序解决选择问题,令 k = N/2。 
*/
#include <stdlib.h>			// use rand () and srand () 动态生成数组
#include <stdio.h>
#include <stdbool.h>		// use bool 
#include <time.h>			// use clock () 计时    use time () 作为 seed
#define MAXLENGTH 500000

void bubble_sort (int a[], int length);
void insert_sort (int a[], int length);
void fun1 (int a[], int length);		// 方法1 
void fun2 (int a[], int length);		// 方法2 
void print_array (int a[], int length);	// 打印输出数组 

int main (void)
{
	int N;
	int i;		// index 
	int a[MAXLENGTH];
	clock_t start, finish;			// 分别记录开始和结束时的 clock() 值
	 
// 用随机函数产生数组 
	printf ("How many numbers you want to analysis?(q to quit)\n");
	while (scanf ("%d", &N) == 1)		// 循环进行输入分析过程。 
	{
		srand (time (0));			// use current time as seed for random generator
		for (i = 0; i < N; i++)
		{
			a[i] = rand() % N;
		}
	//	printf ("the array generated is:\n");
	//	print_array (a, N);
		
		start = clock();
    	fun1 (a, N);			// 第一种方法,用冒泡法排序。 
	//	fun2 (a, N);			// 第二种方法,利用到了插入排序 
		finish = clock();
		printf ("CPU time used %.2f ms\n", 1000 * (double) (finish - start) / CLOCKS_PER_SEC);		// 以毫秒计 		
		printf ("How many numbers you want to analysis?(q to quit)\n");	
	}
	
	return 0;
} 

// 方法一 利用冒泡排序 
void fun1 (int a[], int length)
{
	bubble_sort (a, length);
//	printf ("Now the array is:\n");
//	print_array (a, length);
	printf ("The %dth big number is %d\n", length/2, a[length/2 - 1]);
}

// bubble sort max to min
void bubble_sort (int a[], int length)
{
	int i, j, temp;
	bool swap;
	for (i = 0; i < length - 1; i++)		// length - 1 times
	{
		swap = false;
		for (j = 0; j < length -1 -i; j++)
		{
			if (a[j] < a[j+1])
			{
				swap = true;
				temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
		if (!swap)
			break;
	}
	return;
}

// 第二种方法 利用插入排序 
void fun2 (int a[], int length)
{
	int b[length / 2];			// 长度为  length / 2
	int i, j;
	// 构造 b 数组 为 a 的前 length / 2 个 元素所构成, 并递减排序 
	for (i = 0; i < length / 2; i++)
	{
		b[i] = a[i];
	}
	insert_sort (b, length / 2);
//	printf ("array b:\n");
//	print_array (b, length / 2);	
	// 开始向 b 中插入剩下的 a 中元素	思想与插入排序类似,只是注意对于 b 中 最后一个元素的处理。要用倒数第二个去覆盖,而不用后移。 
	for (i = length / 2; i < length; i++) 
	{
		if (a[i] <= b[length / 2 - 1])		// 比 b 的最后一个元素小,不插入 
			continue;
		// 比最后一个元素大,插入。 
		for (j = length / 2 - 2; j >= 0 ; j--)	// a[i] 直接与 b 的倒数第二个元素比较 
		{
			if (a[i] > b[j])
			{
				b[j+1] = b[j];	 
			}
			else
				break; 
		}
		if (j >= 0)
			b[j+1] = a[i];
		else
			b[0] = a[i];	
	}
//	printf ("Now the array is:\n");
//	print_array (b, length/2);
	printf ("The %dth big number is %d\n", length/2, a[length / 2 - 1]);
}

// 插入排序 下标从0开始,与之前所学有略微差别。
void insert_sort (int a[], int length) 
{
	int i, j, temp;
	
	for (i = 1; i < length / 2; i++)
	{	
		temp = a[i];
		for (j = i-1; j >= 0; j--)
		{
			if (temp > a[j])		// temp 较大,把小的后移 
				a[j+1] = a[j];		// 将小的元素后移
			else					// temp 较小, 则需考虑将temp插入 
				break;
		}
		if (j >= 0)
			a[j+1] = temp;
		else				// j < 0 即 j = -1 说明 temp > b[0] 
			a[0] = temp;
	}
}


// 打印整型数组 
void print_array (int a[], int length) 
{
	int i;
	for (i = 0; i < length; i++)
		printf ("%d\t", a[i]);
	printf ("\n");
}




/*
when I use fun1 to do this, the time(ms) table :
 
N:  100     1000    2000    4000    10000   15000   20000   30000   40000   50000
T:  0.18    9.13    35.30   103.27  370.25  800.65  1373.49 3013.20 5324.30 8325.52
N:  60000   70000   80000   90000   100000
T:  12301.9 16343.7 22047.7 29176.4 33550.90
when I use fun1 to do this, the time table :

N:  100     1000    2000    4000    10000   15000   20000   30000   40000   50000
T:  0.06    0.35    0.94    3.25    18.54   39.57   61.20   110.23  161.23  215.09
N:  60000   70000   80000   90000   100000
T:  271.17  358.10  411.38  490.30  600.65

可见,方法二比方法一好很多,当然,作者说还有更好的方法,拭目以待
*/
posted @ 2016-01-11 22:10  ice-mj  阅读(182)  评论(0编辑  收藏  举报