70,022
社区成员




/*
10、顺序线性表的操作
使用带头指针的单链表表示顺序线性表,结点的数据域包括(数据、是否是素数),通过函数分别实现以下操作的算法。
实现要求:定义实现以下操作的函数
⑴ 顺序表的建立:键盘输入顺序表的元素个数n,通过随机生成的方式生成在[100,100000]之间的奇数,判断是否是素数并修改相应的数据域。
⑵ 输出顺序表的所有元素。
⑶ 求出顺序表中值最小和次小的素数,最小和次小的素数通过指针变量带回,函数不需要返回值。
⑷ 删除顺序表中值在S与T之间(S和T的大小关系任意)的所有元素,若S和T不合理或顺序表位空则显示错误信息。
⑸ 删除顺序表中所有值重复的所有元素,使得顺序表中的所有元素两两互不相同,然后调用函数输出处理之后的顺序表的所有元素。
⑹ 顺序表的逆序。包括输出逆序前顺序表、输出逆序后顺序表。
⑺ 设计一个菜单,上述操作要求都作为菜单中的主要菜单项。
*/
#include"stdio.h"
#include"time.h"
#include"stdlib.h"
#include"malloc.h"
struct digit
{
int number;
int type;
struct digit *next;
};
struct digit * create_link_table()
{
int i, numb, j, m, ty = 0, n;
printf("请输入顺序线性表的元素个数n:");
scanf("%d", &n);
struct digit *head = NULL;
for (i = 1; i <= n; i++) //循环一:建立n个结点的链表
{ //开辟一个新结点
struct digit *p1 = NULL, *p2 = NULL;
if ((p1 = (struct digit *)malloc(sizeof(struct digit))) == NULL) //分配n个int型储存块返回首地址
{
printf("不能成功分配储存块!!\n");
exit(0);
}
p1->next = NULL; //令新结点指针域为NULL
for (j = 1; j > 0; j++) //循环二:给链表随机赋值
{
srand(time(NULL));
numb = rand() % 100001;
if (numb >= 100 && numb <= 100000 && numb % 2 == 1) //判断是否符合100~100000、奇数
{
for (m = 3; m < numb; m += 2) //循环三:判断是否为素数
{
for (n = m; m < numb; n += 2) //循环四
{
if (m*n == numb) //若为素数,保存ty为1,跳出循环四
{
ty = 1;
break;
}
}
if (ty == 1)break; //跳出循环三
}
p1->number = numb; //赋
p1->type = ty;
if (i == 1)head = p1;
else p2->next = p1; //值,表尾链入新结点
p2 = p1; //p2指向新的表尾结点
break; //赋值成功,重新进行循环一
}
else continue; //随机数不符合条件,重新赋值
}
}
printf("建立顺序线性表成功!\n");
return head;
}
void Print()
{
}
void Getsmallest()
{
}
void deleteST()
{
}
void deletesame()
{
}
void changeorder()
{
}
void menu()
{
printf(" 顺序线性表的操作 \n");
printf("=====================================\n");
printf(" 1-建立顺序表 2-输出顺序表 \n");
printf(" 3-求最小与次小 4-删除S与T间元素 \n");
printf(" 5-删除重复值 6-输出逆序表 \n");
printf(" 0-退出 \n");
printf("=====================================\n");
printf(" 请选择输入(1-6,0退出):");
}
void main()
{
struct digit * head = NULL;
int i, sel;
for (i = 0; i >= 0; i++)
{
menu();
scanf("%d", &sel);
switch (sel)
{
case 1:
head = create_link_table();
break;
case 0:
printf("已退出顺序线性表的操作\n");
return;
default:
printf("输入错误,请重新选择!\n");
break;
}
}
}
#include"stdio.h"
#include"stdlib.h"
#include"malloc.h"
struct digit
{
int number;
int type;
struct digit *next;
};
struct digit * Create()
{
int i, numb, ty = 0, n=20;
printf("请输入顺序线性表的元素个数n:");
// scanf("%d", &n);
printf("20\n");
struct digit *head = NULL;//生成头结点 ,用头指针head指向头结点
if ((head = (struct digit *)malloc(sizeof(struct digit))) == NULL) //分配了一个不存放有效数据的头结点
{
printf("不能成功分配头结点!!\n");
exit(0);
}
struct digit *p2 = head;//永远指向尾结点 ,初始状态先赋头结点给它
p2->next = NULL; //尾结点指针指向NULL
struct digit *p1 = NULL;
for (i = 1; i <= n; i++) //循环一:建立n个结点的链表
{ //开辟一个新结点
if ((p1 = (struct digit *)malloc(sizeof(struct digit))) == NULL) //分配n个int型储存块返回首地址
{
printf("不能成功分配储存块!!\n");
exit(0);
}
numb=i%4+1;
p1->next = NULL; //令新结点指针域为NULL
p1->number = numb; //赋
p1->type = ty;
p2->next = p1; //值,表尾链入新结点
p1->next = NULL;
p2 = p1; //p2指向新的表尾结点
}
return head;
}
struct digit * Deletesame(struct digit * head)
{
struct digit * p1=head,* p2=head,* p3=head;
p1=p1->next;
for(;p3->next!=NULL;)
{
for(;p1!=NULL;)
{
if(p3->number==p1->number) //符合删除条件
{
p2->next=p1->next;
free(p1);
// p2=p2->next;
p1=p2;
p1=p1->next;
}
else
{
p2=p1;
p1=p1->next;
}
}
/* if(p3->number==p1->number) //检测最后一个
{
p2->next=NULL;
free(p1);
p1=NULL;
}*/
p3=p3->next; //完成一个数字的删除重复值,p3指向下一个数字
p1=p3;p2=p3; //p1、p2重新指向p3
printf("ok\n");
p1=p1->next; //p1往后移动1次,之后可以再次比较
}
return head;
}
void Print(struct digit * head)
{
struct digit * p = head; //定义p指针指向链表第一个结点
printf(" %-5s %-5s\n", "数值", "类型");
p = p->next;
while (p != NULL)
{
printf(" %-5d ",p->number);
if(p->type==0)printf(" 素数\n");
else printf("非素数\n");
p = p->next; //指向下一个节点
}
}
void main()
{
struct digit * head;
head = Create();
Print(head);
head = Deletesame(head);
printf("删除后:\n");
Print(head);
}
p3用于遍历链表;p1用于遍历p3后面的结点;p2用于追踪p1,方便删除结点。结果这个函数跳不出循环了。。。
int is_prime(int p);
struct digit *create_link_table()
{
int i, numb, j, m, ty = 0, n, nx;
printf("请输入顺序线性表的元素个数n:");
scanf("%d", &n);
struct digit *head = NULL;
// 在循环一的外面定义p1、p2
struct digit *p1 = NULL, *p2 = NULL;
for (i = 1; i <= n; i++) //循环一:建立n个结点的链表
{ //开辟一个新结点
//struct digit *p1 = NULL, *p2 = NULL;
if ((p1 = (struct digit *)malloc(sizeof(struct digit))) == NULL) //分配n个int型储存块返回首地址
{
printf("不能成功分配储存块!!\n");
exit(0);
}
p1->next = NULL; //令新结点指针域为NULL
// 要用死循环的话,建议使用while(1),
// 下面这样的for循环,变量 j 的值有可能溢出而导致意外退出循环
//for (j = 1; j > 0; j++) //循环二:给链表随机赋值
while (1) {
srand(time(NULL));
numb = rand() % 100001;
if (numb >= 100 && numb <= 100000 && numb % 2 == 1) //判断是否符合100~100000、奇数
{
// 判断 numb 是否为素数
if (is_prime(numb)) {
p1->number = numb;
p1->type = 1;
} else {
continue;
}
/*
for (m = 3; m < numb; m += 2) //循环三:判断是否为素数
{
// 把元素个数变量 n 改变了,影响了循环一的条件
// 定义新变量 nx
for (nx = m; m < numb; nx += 2) //循环四
{
// 这是素数么?!
if (m * nx == numb) //若为素数,保存ty为1,跳出循环四
{
ty = 1;
break;
}
}
if (ty == 1)
break; //跳出循环三
}
p1->number = numb; //赋
p1->type = ty;
*/
if (i == 1)
head = p1;
else
// 每次都在循环一内部重新定义p2,但是却没有给p2分配内存空间
p2->next = p1; //值,表尾链入新结点
p2 = p1; //p2指向新的表尾结点
break; //赋值成功,重新进行循环一
} else
continue; //随机数不符合条件,重新赋值
}
}
printf("建立顺序线性表成功!\n");
return head;
}
// 检查 p 是否为素数
int is_prime(int p)
{
if (p < 2)
return 0;
if (p > 2 && p % 2 == 0)
return 0;
int i;
for (i = 2; i < p; i++) {
if (p % i == 0)
break;
}
if (i == p) {
return 1;
} else {
return 0;
}
}