数据结构作业-计算链表节点个数,将链表逆置,删除链表中值为X的节点的前驱结点的算法

//链表的建立,遍历
//数据结构作业 

//1.计算结点个数(更改,题意理解错误:计算值为x的节点的个数) 
        //方法:新建指针,从头遍历链表,若s->next != NULL,则计数器加一
        
//2.将链表L逆置(头变尾,尾变头)
        //方法:1.用头插法新建链表,并从头遍历原链表赋值给新链表
        //      2.对于原链表从前往后拿出结点前插法插入新链表
        
//3.删除链表中值为x的前一结点
        //方法:新建两个指针,一前一后指向原链表,若后一指针p->next->next找到,则删除p所对结点
        //后计划更改:发现无法实现前几个元素的更改,后发现链表性质,可以直接判断p->next值从而寻找目标以及删除
        //再次更改:理解错误,还是需要原先方法,但可让另一个指向头指针,前几个也可以删除 
        //更改:2018.9.26
        //删除了当前节点,而不是前一结点 

#include <stdio.h>
#include <stdlib.h>

typedef struct LinkList                         //定义单链表结构体,并为定义方式重新起名 
{
	int data;
	struct LinkList *next;
} LinkList;                                     //链表结构体定义名称为LinkList 

/*链表初始化*/ 
void *star(LinkList **head)                     //初始化链表,然后方便输入 
{
	*head=(LinkList*)malloc(sizeof(LinkList));  //初始化分配内存,空间 
	(*head)->next=NULL;                         //尾指针至为空 
}

/*链表建立*/ 
LinkList Get_LinkList(int x,LinkList *p)
{
	LinkList *s;
	s=(LinkList*)malloc(sizeof(LinkList));      //分配新空间 
	s->next=p->next;                            //头查法建表 
	p->next=s;
	s->data=x; 
}

//遍历链表并输出 
void all(LinkList *p)
{
	LinkList *s;                           //新建指针指向头节点 
	s=p->next;
	while(s!=NULL)
	{
	//	putchar(s->data);
		printf("%d",s->data);
		s=s->next;
		putchar('\n');
	}
	putchar('\n');
	
}

//1.计算结点个数
int lenth(LinkList *p)
{
	int x=0,i;                                   //计数器,计算节点个数 
	LinkList *s;
	s=p->next;
	printf("请输入X:");
	scanf("%d",&i); 
	while(s!=NULL)                             //若不为空,则计数器加一 
	{
		if(s->data==i)
		{
			x++;
			s=s->next;
		}
		s=s->next;
		
	} 
	
	
	return x;                                  //返回计数器的值 
} 

//2.将链表L逆置(头变尾,尾变头)
      //方法一 
void change(LinkList *p,LinkList *q)                  //将两个链表导入,p为原链表,q为新链表 
{
	LinkList *s,*d;                                   //新建两个指针,s对于链表q建表,d指向p链表头节点 
	d=p->next;
	while(d!=NULL)                                    //若d指向结点不为NULL,则进行链表以及赋值运算 
	{
		s=(LinkList*)malloc(sizeof(LinkList));        //进行建表,以及赋值 
		s->data=d->data;
		s->next=q->next;
		q->next=s;
		d=d->next;                                    //赋值完成指向下一个元素 
	}
}

//3.删除链表中值为x的前一结点
int delete(LinkList *p)
{
	int i;
	printf("请输入想删除的元素:");
	scanf("%d",&i); 
	//定义两个指针,一个X用于存所找元素地址,另一个s用于遍历链表 
	//更改:两个指针一前一后 
	LinkList *s,*x,*q;					/**s,*x;*/ //新定义两个指针(原计划)/*更改:发现无法实现前几个元素的删除,后发现链表性质,计划更改*/
	s=p->next;                                 //再次更改 
	x=p;                               //两个指针相邻指向    
	while(s->data!=i)                          //判断是否为所找元素 
	{
		if(s->next==NULL)                      //若不是所找元素,则判断是否为空,防止溢出 
		{
			printf("不存在这个元素");
			return 0;
		}
		s=s->next;                             //若都不是,则说明没有找到,则后移继续查找 
		x=x->next; 
		
	} 
	q=p->next;
	while(q->next!=x)
	{
		q=q->next;
	}
	if(s->data==i)                             //若找到,则进入判断 
	{
		q->next=s;                       //断开连接 
		x->next=NULL;
		free(x);                               //释放空结点 
		return 0;
	}
} 

int main() 
{
	int i,x,num1;                              //x为输入值,i为控制输入次数,num为长度(节点个数) 
	LinkList *p,*q;
	star(&p);
	star(&q);                                  //初始化链表 
	for(i=0;i<8;i++)                           //输入8个元素 
	{
		printf("The %d=",i);                    
		scanf("%d",&x);
		//getchar();                           //缓冲区,输入元素后存入回车,以防存入回车 
		Get_LinkList(x,p);                     //建立链表 
	}
	num1=lenth(p);                             //返回长度 
	printf("%d\n",num1);
	all(p);                                    //输出链表中全部元素 
	change(p,q);                               //将链表逆置 
	all(q);                                    //输出逆置后元素 
	delete(p);
	all(p);
	return 0;
}


//2018.9.24 

  1.  

/*问题一:额外getchar()函数:getchar()函数为输入一个字符,可以是任意种类,因此,输入元素以后如果按下回车和空格键
                    相当于输入元素,以及回车和空格,就会造成下一次直接从第三个元素开始输入,因此,用一个
                    额外的getchar()函数作为缓冲,存入空格和回车*/
                    
/*问题二:尝试更改getchar()函数为scanf函数以及putchar()和printf,后发现,不可以混合使用*/ 
/*问题三:对于删除运算的应用,以及单链表的理解*/ 

//待解决问题:初始化使用指针函数以及**head的原因 

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值