手动写一个链表,之前很顺畅,这次不知因为什么卡了好久,看明白之后对你很有帮助,最起码简单的链表可以自己解决了,仔细的琢磨一下,不懂的就自己手动画画图,自己画懂才是硬道理。
正文
#include<stdlib.h>
int count =0; //计算链表内的节点个数
typedef struct SNode //定义结构体
{
int data; //数据域,存储数据
struct SNode *next; //指针域,存储下一个节点的地址
}Link;
Link* GetLink() //创造头节点并返回
{
Link *p = (Link*)malloc(sizeof(Link)); //在堆内存上开辟一块空间,防止消失
if ( NULL == p ) { //如果开辟失败为NULL
printf("malloc error\n"); //打印错误信息
return NULL; //返回没必要继续执行
}
p->next=NULL; //如果开辟成果初始化
p->data=0;
return p; //返回地址
}
void AddMember(Link *p,int data) //添加成员
{
while( p->next != NULL ) //找到链表的末尾
{
p=p->next; //不断的循环去找下一个节点,直到最后一个节点
}
Link *q;
q = (Link*)malloc(sizeof(Link)); //创建一个新的节点
if ( NULL == q ) //对新节点进行判断,是否开辟成功
{
printf("AddMember malloc error\n"); //没成功打印错误信息
return; //返回,不需要继续执行;
}
q->data = data; //初始化新节点
q->next = NULL; //新节点没有下一个节点,所以next为NULL
p->next = q; //链表的最后一个节点指向新节点
count++; //计数变量自增1
}
void Print(Link *p) //遍历链表
{
while(p->next!=NULL) //当p没有下一个节点时候退出循环
{
p = p->next; //由于有头节点GetLink()创建的,所以跳过头结点
printf("%d\n",p->data); //打印数据域
}
}
void RemovData(Link *p,int data) //删除数据
{
while( p->next != NULL ) //当p没有下一个节点时候退出循环
{
if( p->next->data == data ) //p的下一个节点的数据域是想删除的数据
{
break;
}
p=p->next; //如果不break,p会一直向下走
}
if(p->next = NULL) //如果走到最后没有找到,p->next为NULL代表最后一个节点
{
printf("没有对应的数据:%d,删除失败\n",data);//打印没找到信息
return; //结束函数,没必要继续向下执行
}
Link *q = p ->next; //创建一个新节点为p的下一个节点(所删除的节点)
p->next = q->next; //令链表跳过所删除的节点,直接指向所删除节点的下一个节点
free(q); //释放掉所删除的节点(由于是在堆上开辟的空间)
count--;
}
void ChangeData(Link *p,int pos,int data) //修改指定位置的数据
{
int i=0; //i为计算走的步数
if(pos>count) //如果所改变的位置大于节点个数不符合规范
{
printf("pos error\n"); //打印错误信息
return; //结束函数
}
for(i=0;i<pos+1;i++) //由于头节点为空所以多走一步
{
p = p->next; //p不断向下一个节点移动
}
p->data=data; //修改数据域
}
void Reverse(Link *h) //链表逆转
{ //链表反转,这里需要借助两个临时的Link变量,如果有不理解的小伙伴
//可以先琢磨其他部分,然后在研究这里。理解之后不难的,自己画图按照逻辑画一遍;
Link *h,*q;
p=h->next; //p在头部的下一个节点,想要逆转需要把链表的头部变成尾部,h作为头结点不改变位置
q=p; //q和p在同一节点,为头结点的下一个节点
h->next=NULL; //先断开头结点
while(q)
{
q=q->next; //这句我不明白为啥非要放在这我才会正常运行,向下挪一行都不行,只是用作判断是否为最后一个节点。
p->next = h->next; //p->next指向h的next;
h->next = p; //h->next指向p所在的节点
p=q; //p到q的位置
}
}
int main()
{
Link *p = GetLink();
if( NULL == p )
{
printf("GetLink error\n");
return -1;
}
AddMember(p,5);
AddMember(p,4);
AddMember(p,3);
AddMember(p,2);
AddMember(p,1);
ChangeData(p,3,10)
Print(p);
printf("------------------\n");
Reverse(p);
Print(p);
printf("------------------\n");
RemovData(p,30);
RemovData(p,5);
RemovData(p,1);
Print(p);
}
输出结果为
5
4
3
10
1
------------------
1
10
3
4
5
------------------
没有对应的数据 30
10
3
4