算法实例

经典排序与查找算法
本文详细介绍了多种排序算法(如直接插入排序、希尔排序、冒泡排序等)及查找算法(如二分查找、分块查找等)的具体实现,并通过示例展示了斐波那契数列、哥德巴赫猜想等数学概念的应用。

直接插入排序
希尔排序  
  冒泡排序  
  快速排序  
  选择排序  
  归并排序  
  二分查找  
  分块查找  
  哈希查找  
斐波那契数列  
哥德巴赫猜想 
尼科彻斯定理 

// ConsoleApplication4.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#pragma warning(disable:4996)
//#define 直接插入排序
//#define 希尔排序	 
//#define  冒泡排序	 
//#define  快速排序	 
//#define  选择排序	 
//#define  归并排序	 
//#define  二分查找	 
//#define  分块查找	 
//#define  哈希查找	 
//#define  斐波那契数列	 
//#define  哥德巴赫猜想	 
#define  尼科彻斯定理	 
#ifdef 直接插入排序
void insort(int s[], int n)							/*自定义函数isort*/
{
	int i, j;
	for (i = 2; i <= n; i++)					/*数组下标从2开始,0做监视哨,1一个数据无可比性*/
	{
		s[0] = s[i];								/*给监视哨赋值*/
		j = i - 1;								/*确定要进行比较的元素的最右边位置*/
		while (s[0] < s[j])
		{
			s[j + 1] = s[j];							/*数据右移*/
			j--;								/*移向左边一个未比较的数*/
		}
		s[j + 1] = s[0];							/*在确定的位置插入s[i]*/
	}
}

void main()
{
	int a[11], i;									/*定义数组及变量为基本整型*/
	printf("请输入10个数据:\n");
	for (i = 1; i <= 10; i++)
		scanf("%d", &a[i]);							/*接收从键盘中输入的10个数据到数组a中*/
	printf("原始顺序:\n");
	for (i = 1; i < 11; i++)
		printf("%5d", a[i]);							/*将未排序前的顺序输出*/
	insort(a, 10);									/*调用自定义函数isort()*/
	printf("\n插入数据排序后顺序:\n");
	for (i = 1; i < 11; i++)
		printf("%5d", a[i]);							/*将排序后的数组输出*/
	printf("\n");
}
#endif // 直接插入排序

#ifdef 希尔排序
#include <stdio.h>

void shsort(int s[], int n)									/*自定义函数shsort*/
{
	int i, j, d;
	d = n / 2;											/*确定固定增量值*/
	while (d >= 1)
	{
		for (i = d + 1; i <= n; i++)								/*数组下标从d+1开始进行直接插入排序*/
		{
			s[0] = s[i];									/*设置监视哨*/
			j = i - d;										/*确定要进行比较的元素的最右边位置*/
			while ((j > 0) && (s[0] < s[j]))
			{
				s[j + d] = s[j];								/*数据右移*/
				j = j - d;									/*向左移d个位置*/
			}
			s[j + d] = s[0];									/*在确定的位置插入s[i]*/
		}
		d = d / 2;										/*增量变为原来的一半*/
	}
}

void main()
{
	int a[11], i;											/*定义数组及变量为基本整型*/
	printf("请输入10个数据:\n");
	for (i = 1; i <= 10; i++)
		scanf("%d", &a[i]);									/*从键盘中输入10个数据*/
	shsort(a, 10);										/*调用shsort()函数*/
	printf("排序后的顺序是:\n");
	for (i = 1; i <= 10; i++)
		printf("%5d", a[i]);									/*将排好序的数组输出*/
	printf("\n");
}

#endif // 希尔排序

#ifdef 冒泡排序
#include <stdio.h>

void main()
{
	int i, j, t, a[11];								/*定义变量及数组为基本整型*/
	printf("请输入10个数:\n");
	for (i = 1; i < 11; i++)
		scanf("%d", &a[i]);							/*从键盘中输入10个数*/
	for (i = 1; i < 10; i++)							/*变量i代表比较的趟数*/
		for (j = 1; j < 11 - i; j++)						/*变量j代表每趟两两比较的次数*/
			if (a[j] > a[j + 1])
			{
				t = a[j];									/*利用中间变量实现俩值互换*/
				a[j] = a[j + 1];
				a[j + 1] = t;
			}
	printf("排序后的顺序是:\n");
	for (i = 1; i <= 10; i++)
		printf("%5d", a[i]);							/*将冒泡排序后的顺序输出*/
	printf("\n");
}

#endif // 冒泡排序
#ifdef 快速排序
#include <stdio.h>

void qusort(int s[], int start, int end)									/*自定义函数qusort()*/
{
	int i, j;													/*定义变量为基本整型*/
	i = start;												/*将每组首个元素赋给i*/
	j = end;												/*将每组末尾元素赋给j*/
	s[0] = s[start];											/*设置基准值*/
	while (i < j)
	{
		while (i < j && s[0] < s[j])
			j--;											/*位置左移*/
		if (i < j)
		{
			s[i] = s[j];										/*将s[j]放到s[i]的位置上*/
			i++;											/*位置右移*/
		}
		while (i < j && s[i] <= s[0])
			i++;											/*位置右移*/
		if (i < j)
		{
			s[j] = s[i];										/*将大于基准值的s[j]放到s[i]位置*/
			j--;											/*位置右移*/
		}
	}
	s[i] = s[0];												/*将基准值放入指定位置*/
	if (start < i)
		qusort(s, start, j - 1);									/*对分割出的部分递归调用函数qusort()*/
	if (i < end)
		qusort(s, j + 1, end);
}

void main()
{
	int a[11], i;												/*定义数组及变量为基本整型*/
	printf("请输入10个数:\n");
	for (i = 1; i <= 10; i++)
		scanf("%d", &a[i]);										/*从键盘中输入10个要进行排序的数*/
	qusort(a, 1, 10);											/*调用qusort()函数进行排序*/
	printf("排序后的顺序是:\n");
	for (i = 1; i <= 10; i++)
		printf("%5d", a[i]);										/*输出排好序的数组*/
	printf("\n");
}

#endif // 快速排序
#ifdef 选择排序
#include<stdio.h>

void main()
{
	int i, j, t, a[11];					/*定义变量及数组为基本整型*/
	printf("请输入10个数:\n");
	for (i = 1; i < 11; i++)
		scanf("%d", &a[i]);				/*从键盘中输入要排序的10个数字*/
	for (i = 1; i <= 9; i++)
		for (j = i + 1; j <= 10; j++)
			if (a[i] > a[j])				/*如果后一个数比前一个数大则利用中间变量t实现俩值互换*/
			{
				t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
	printf("排序后的顺序是:\n");
	for (i = 1; i <= 10; i++)
		printf("%5d", a[i]);				/*将排好序的数组输出*/
	printf("\n");
}

#endif // 选择排序
#ifdef 归并排序
#include <stdio.h>

void merge(int r[], int s[], int x1, int x2, int x3) /*实现一次归并排序函数*/
{
	int i, j, k;
	i = x1; 										/*第一部分的开始位置*/
	j = x2 + 1; 										/*第二部分的开始位置*/
	k = x1;
	while ((i <= x2) && (j <= x3))
		/*当i和j都在两个要合并的部分中*/
		if (r[i] <= r[j])
			/*筛选两部分中较小的元素放到数组s中*/
		{
			s[k] = r[i];
			i++;
			k++;
		}
		else
		{
			s[k] = r[j];
			j++;
			k++;
		}
	while (i <= x2)
		/*将x1~x2范围内的未比较的数顺次加到数组r中*/
		s[k++] = r[i++];
	while (j <= x3)
		/*将x2+1~x3范围内的未比较的数顺次加到数组r中*/
		s[k++] = r[j++];
}

void merge_sort(int r[], int s[], int m, int n)
{
	int p;
	int t[20];
	if (m == n)
		s[m] = r[m];
	else
	{
		p = (m + n) / 2;
		merge_sort(r, t, m, p);
		/*递归调用merge_sort函数将r[m]~r[p]归并成有序的t[m]~t[p]*/
		merge_sort(r, t, p + 1, n);						/*递归调用merge_sort函数将r[p
														+1]~r[n]归并成有序的t[p+1]~t[n]*/
		merge(t, s, m, p, n); 						/*调用函数将前两部分归并到s[m]~s[n]*/
	}
}

void main()
{
	int a[11];
	int i;
	printf("请输入10个数:\n");
	for (i = 1; i <= 10; i++)
		scanf("%d", &a[i]);
	/*从键盘中输入10个数*/
	merge_sort(a, a, 1, 10);					 /*调用merge_sort函数进行归并排序*/
	printf("排序后的顺序是:\n");
	for (i = 1; i <= 10; i++)
		printf("%5d", a[i]);
	/*将排序后的结构输出*/
	printf("\n");
}

#endif // 归并排序
#ifdef 二分查找
#include<stdio.h>

void binary_search(int key, int a[], int n) /*自定义函数binary_search*/
{
	int low, high, mid, count = 0, count1 = 0;
	low = 0;
	high = n - 1;
	while (low < high)								/*当查找范围不为0时执行循环体语句*/
	{
		count++;								/*count记录查找次数*/
		mid = (low + high) / 2;						/*求出中间位置*/
		if (key < a[mid])							/*当key小于中间值*/
			high = mid - 1;						/*确定左子表范围*/
		else if (key > a[mid])						/*当key大于中间值*/
			low = mid + 1;							/*确定右子表范围*/
		else if (key == a[mid])						/*当key等于中间值证明查找成功*/
		{
			printf("查找成功!\n查找 %d 次!a[%d]=%d", count, mid, key);
			/*输出查找次数及所查找元素在数组中的位置*/
			count1++;							/*count1记录查找成功次数*/
			break;
		}
	}
	if (count1 == 0)								/*判断是否查找失败*/
		printf("查找失败!");							/*查找失败输出no found*/
}

void main()
{
	int i, key, a[100], n;
	printf("请输入数组的长度:\n");
	scanf("%d", &n);								/*输入数组元素个数*/
	printf("请输入数组元素:\n");
	for (i = 0; i < n; i++)
		scanf("%d", &a[i]);							/*输入有序数列到数组a中*/
	printf("请输入你想查找的元素:\n");
	scanf("%d", &key);							/*输入要查找的关键字*/
	binary_search(key, a, n);						/*调用自定义函数*/
	printf("\n");
}

#endif // 二分查找
#ifdef 分块查找
#include <stdio.h>

struct index 									/*定义块的结构*/
{
	int key;
	int start;
	int end;
} index_table[4]; 								/*定义结构体数组*/

int block_search(int key, int a[]) 						/*自定义实现分块查找*/
{
	int i, j;
	i = 1;
	while (i <= 3 && key > index_table[i].key)			/*确定在那个块中*/
		i++;
	if (i > 3)									/*大于分得的块数,则返回0*/
		return 0;
	j = index_table[i].start; 							/*j等于块范围的起始值*/
	while (j <= index_table[i].end && a[j] != key)			/*在确定的块内进行查找*/
		j++;
	if (j > index_table[i].end)						/*如果大于块范围的结束值,则说明没有要查找的数,j置0*/
		j = 0;
	return j;
}

void main()
{
	int i, j = 0, k, key, a[16];
	printf("请输入15个数:\n");
	for (i = 1; i < 16; i++)
		scanf("%d", &a[i]);							/*输入由小到大的15个数*/
	for (i = 1; i <= 3; i++)
	{
		index_table[i].start = j + 1; 					/*确定每个块范围的起始值*/
		j = j + 1;
		index_table[i].end = j + 4; 					/*确定每个块范围的结束值*/
		j = j + 4;
		index_table[i].key = a[j]; 					/*确定每个块范围中元素的最大值*/
	}
	printf("请输入你想查找的元素:\n");
	scanf("%d", &key); 							/*输入要查询的数值*/
	k = block_search(key, a); 						/*调用函数进行查找*/
	if (k != 0)
		printf("查找成功,其位置是:%d\n", k);			/*如果找到该数,则输出其位置*/
	else
		printf("查找失败!");							/*若未找到则输出提示信息*/
}


#endif // 分块查找
#ifdef 哈希查找
#include <stdio.h>
#include <time.h>
#include <windows.h>
#define Max 11
#define N 8
int hashtable[Max];

int func(int value)
{
	return value % Max; 								/*哈希函数*/
}

int search(int key) 									/*自定义函数实现哈希查询*/
{
	int pos, t;
	pos = func(key); 									/*哈希函数确定出的位置*/
	t = pos;										/*t存放确定出的位置*/
	while (hashtable[t] != key && hashtable[t] != -1)
		/*如果该位置上不等于要查找的关键字且不为空*/
	{
		t = (t + 1) % Max; 								/*利用线性探测求出下一个位置*/
		if (pos == t)
			/*如果经多次探测又回到原来用哈希函数求出的位置则说明要查找的数不存在*/
			return  -1;
	}
	if (hashtable[t] == -1)
		/*如果探测的位置是-1则说明要查找的数不存在*/
		return NULL;
	else
		return t;
}

void creathash(int key)								/*自定义函数创建哈希表*/
{
	int pos, t;
	pos = func(key);								/*哈希函数确定元素的位置*/
	t = pos;
	while (hashtable[t] != -1)
		/*如果该位置有元素存在则进行线性探测再散列*/
	{
		t = (t + 1) % Max;
		if (pos == t)
			/*如果冲突处理后确定的位置与原位置相同则说明哈希表已满*/
		{
			printf("哈希表已满\n");
			return;
		}
	}
	hashtable[t] = key;								/*将元素放入确定的位置*/
}

void main()
{
	int flag[50];
	int i, j, t;
	for (i = 0; i < Max; i++)
		hashtable[i] = -1;
	/*哈希表中初始位置全置-1*/
	for (i = 0; i < 50; i++)
		flag[i] = 0;
	/*50以内所有数未产生时均标志为0*/
	srand((unsigned long)time(0)); 					/*利用系统时间做种子产生随机数*/
	i = 0;
	while (i != N)
	{
		t = rand() % 50; 							/*产生一个50以内的随机数赋给t*/
		if (flag[t] == 0)
			/*查看t是否产生过*/
		{
			creathash(t);							/*调用函数创建哈希表*/
			printf("%2d:", t); 						/*将该元素输出*/
			for (j = 0; j < Max; j++)
				printf("(%2d) ", hashtable[j]);
			/*输出哈希表中内容*/
			printf("\n");
			flag[t] = 1; 							/*将产生的这个数标志为1*/
			i++;								/*i自加*/
		}
	}
	printf("请输入你想查找的元素:");
	scanf("%d", &t); 								/*输入要查找的元素*/
	if (t > 0 && t < 50)
	{
		i = search(t);								/*调用search进行哈希查找*/
		if (i != -1)
			printf("查找成功!其位置是:%d\n", i);
		/*若查找到该元素则输出其位置*/
		else
			printf("查找失败!");
		/*未找到输出提示信息*/
	}
	else
		printf("输入有误!");
}


#endif // 哈希查找
#ifdef 斐波那契数列
#include <stdio.h>

void main()
{
	int i;											/*定义整型变量i*/
	long f[31];										/*意义数组为长整形*/
	f[1] = 1, f[2] = 1;									/*数组中的f[1]、f[2]赋初值为1*/
	for (i = 3; i < 31; i++)
		f[i] = f[i - 1] + f[i - 2];							/*数列中从第3项开始每一项等于前两项之和*/
	for (i = 1; i < 31; i++)
	{
		printf("%10ld", f[i]);							/*输出数组中的30个元素*/
		if (i % 5 == 0)
			printf("\n");								/*每5个元素进行一次换行*/
	}
}

#endif // 斐波那契数列
#ifdef 哥德巴赫猜想
#include<stdio.h>

int ss(int i)												/*自定义函数判断是否为素数*/
{
	int j;
	if (i <= 1) 											/*小于1的数不是素数*/
		return 0;
	if (i == 2) 											/*2是素数*/
		return 1;
	for (j = 2; j < i; j++)									/*对大于2的数进行判断*/
	{
		if (i % j == 0)
			return 0;
		else if (i != j + 1)
			continue;
		else
			return 1;
	}
}

void main()
{
	int i, j, k, flag1, flag2, n = 0;
	for (i = 6; i < 100; i += 2)
		for (k = 2; k <= i / 2; k++)
		{
			j = i - k;
			flag1 = ss(k);										/*判断拆分出的数是否是素数*/
			if (flag1)
			{
				flag2 = ss(j);
				if (flag2)									/*如果拆分出的两个数均是素数则输出*/
				{
					printf("%3d=%3d+%3d,", i, k, j);
					n++;
					if (n % 5 == 0)
						printf("\n");
				}

			}
		}
	printf("\n");
}

#endif // 哥德巴赫猜想
#ifdef 尼科彻斯定理
#include <stdio.h>

void main()
{
	int i, j, k = 0, l, n, m, sum, flag = 1;
	printf("请输入一个数:\n");
	scanf("%d", &n);									/*从键盘中任意输入一个数*/
	m = n * n * n;										/*计算出该数的立方*/
	i = m / 2;
	if (i % 2 == 0)										/*当i为偶数时i值加1*/
		i = i + 1;
	while (flag == 1 && i >= 1)								/*当i大于等于1且flag=1时执行循环体语句*/
	{
		sum = 0;
		k = 0;
		while (1)
		{
			sum += (i - 2 * k);								/*奇数累加求和*/
			k++;
			if (sum == m)									/*如果sum与m相等,则输出累加过程*/
			{
				printf("%d*%d*%d=%d=", n, n, n, m);
				for (l = 0; l < k - 1; l++)
					printf("%d+", i - l * 2);
				printf("%d\n", i - (k - 1) * 2);					/*输出累加求和的最后一个数*/
				flag = 0;
				break;
			}
			if (sum > m)
				break;
		}
		i -= 2;											/*i等于下一个奇数继续上面过程*/
	}
}

#endif // 尼科彻斯定理


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值