建立线性表,时而成功,时而非正常退出Process exited with return value 3221225725

鹿鳴嗷嗷 2019-05-02 12:09:15

/*
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;
}
}
}


刚接触链表,不知道为什么运行结果有时可以建立线性表有时又不行
...全文
330 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
鹿鳴嗷嗷 2019-05-04
  • 打赏
  • 举报
回复
删除重复结点函数又出了问题,下面是该函数及测试代码
#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,方便删除结点。结果这个函数跳不出循环了。。。
鹿鳴嗷嗷 2019-05-02
  • 打赏
  • 举报
回复
鹿鳴嗷嗷 2019-05-02
  • 打赏
  • 举报
回复
鹿鳴嗷嗷 2019-05-02
  • 打赏
  • 举报
回复
引用 5 楼 weixin_45007129 的回复:
在外面定义一次指针变量,后面在循环里面逐次分配新的内存空间,并不矛盾啊。
对对对我就是这个意思,没表达好
小心你的背后 2019-05-02
  • 打赏
  • 举报
回复
在外面定义一次指针变量,后面在循环里面逐次分配新的内存空间,并不矛盾啊。
鹿鳴嗷嗷 2019-05-02
  • 打赏
  • 举报
回复
谢谢!我自己解决啦~因为代码不是我写的是同学有错误不懂来问我,我急着回复没仔细看,今天花了一个小时才找出错误~~就是要在循环外定义p2(尾结点指针),不过p1是新建结点,每建一个分配一次空间给它,所以还是在for循环内定义~~感谢大佬!!!
拥抱Linux 2019-05-02
  • 打赏
  • 举报
回复
(1)没见过这样的素数判定条件,素数的定义说的就是只有1和它本身这两个因数而已,为啥还有 m * n == numb 呢?
(2)指针 p1 、p2 定义在循环一内部,也就是说,每次进入循环一,就重新定义了两个指针变量 p1 、p2,但是又只给 p1 分配了内存空间,而没有给 p2 分配内存空间,所以从第二次的循环一开始, p2->next 就是非法的了。所以,应该把 p1 、 p2 的定义 放到循环一的前面,就跟 head 的定义 放在一起就可以了。
(3)循环二的循环,理论上存在变量 j 超出 int 的取值范围而导致循环意外退出的可能, 所以 死循环的话,建议使用 while(1)。
具体内容详见注释,自己也调试一下,看看程序运行过程中各个变量的值的情况吧。

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;
}
}

70,022

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧