单链表实现Eratosthenes筛选法

对于任意正整数N,Eratosthenes筛法可表示如下:

第1步,找出小于等于√N的全部素数:p1、p2、p3、…pm。

第2步,在1~N中分别划去p1、p2、…pm全部倍数(除了他们自己本身)。

第2步完成后剩下的整数除1外就是不超过N的全部素数。

简而言之,筛选原理如下:对于一个正整数a<=N,如果素数p1、p2、…、pm(小于等于√N)都不整除a,则a是素数。

下面是C++的单链表实现:

#include <iostream>
#include<cmath>
using namespace std;
const int N(20);//设置所能求的最大数,这里为400
struct Node
{
	int data;
	Node *next;
};
class Eratosthenes
{
public:
	Eratosthenes(int n);//将1-n按顺序生成单链表,头插法生成单链表
	void Delete(Node *p);//删除p指向的节点的后一个结点
	void sqrtN();//求n的平方根,并将小于√n的所有素数放入数组中
	int Factorial(int n);//递归求阶乘
	void De();//筛选出number中各素数的倍数,并删除,p,q指向相邻结点
	void print();//输出所有素数
private:
	int number[N],X,a;//储存小于√n的所有素数,X为传入的数,a记录数组实际长度
	Node *p, *q,*head;
};
Eratosthenes::Eratosthenes(int n)
{
	int x;
	x = int(sqrt(n));
	X = n;
	Node *s;
	head = new Node; head->next = NULL;
	for (int i = X; i >=x; i--)//头插法生成单链表按升序排序
	{
		s = new Node;
		s->data = i; 
		s->next = head->next;
		head->next = s;
	}
}
void Eratosthenes::Delete(Node *t)
{
	Node *w;//配合t删除t后一个结点
	w = t->next;
	t->next = w->next;
	delete w;
}
void Eratosthenes::sqrtN()
{
	double x = sqrt(X);//sqrt()返回值为double类型
	int t ,y=0;
	t = int(x);//强制类型转换
	a = 0;
	for (int i =2 ; i < t; i++)
		if (Factorial(i - 1) % i == (i - 1))//威尔逊定理判断素数
		{
			number[y++] = i;
			a++;
		}
}
void Eratosthenes::De()
{
	for (int i = 0; i < a; i++)//筛选出单链表中为number数组中各值的倍数时的data值,并删除相应的结点
	{
		p = head; q = p->next;
		while (q->next != NULL)
		{
			if ((q->data)%number[i] == 0)//筛选number[i]的倍数,并删除对应data值相应的结点
			{
				Delete(p);
				q = p->next;
			}
			else
			{
				p = q; q = q->next;
			}
		}
	}
}
int Eratosthenes::Factorial(int n)//递归函数求阶乘
{
	if (n == 1)return 1;
	return n * Factorial(n - 1);
}
void Eratosthenes::print()
{
	int t = 1;//控制输出格式
	for (int i = 0; i < a; i++)
		cout << number[i] << '\t';//输出number数组中的值,这些值也是需要求的n以内的素数
	cout << endl;
	q = head->next;
	while (q->next != NULL)//输出节点中筛选出number数组中各值的倍数后剩下的值,即n以内的素数
	{
	    cout << q->data << "\t";
		if (t == a)	{cout << endl;t = 0;}//控制输出格式
		q = q->next;
		t++;
	}
}
int main()
{
	int n;
	cout << "请输入N:(求N以内的所有素数)";
	cin >> n;
	Eratosthenes T(n);
	T.sqrtN();
	T.De();
	T.print();
	return 0;
}
 
 
 

猜你喜欢

转载自blog.csdn.net/song_10/article/details/85005182