//链表的建立,遍历
//数据结构作业
//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
/*问题一:额外getchar()函数:getchar()函数为输入一个字符,可以是任意种类,因此,输入元素以后如果按下回车和空格键
相当于输入元素,以及回车和空格,就会造成下一次直接从第三个元素开始输入,因此,用一个
额外的getchar()函数作为缓冲,存入空格和回车*/
/*问题二:尝试更改getchar()函数为scanf函数以及putchar()和printf,后发现,不可以混合使用*/
/*问题三:对于删除运算的应用,以及单链表的理解*/
//待解决问题:初始化使用指针函数以及**head的原因