#include<stdio.h>
#include<stdlib.h>
struct ListNode{
int data;
struct ListNode* next;
}
//链表的创建——不带头节点
struct ListNode* CreateList(int lenth)
{
struct ListNode *head=NULL,*r=NULL;//这里定义了一个head指针,只是为了返回整个链表的第一个节点
for(int i=0;i<lenth;i++)
{
struct ListNode* p=(struct ListNode*)malloc(sizeof(struct ListNode));
p->data=i;
if(i==0)
{
head=p;
r=p;//尾插法,让r指针始终指向新建节点的前一个节点
continue;//往前跳,重新判断循环条件
}
r->next=p;
r=p;
}
r->next=NULL;
return head;
}
//链表的创建——带头节点
struct ListNode* CreateList(int lenth)
{
//循环外创建头节点,使用尾插法让指针r始终指向新建节点的前一个节点
struct ListNode* head=(struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* r=head;
r->data=lenth;//头节点存储链表长度
for(int i=0;i<lenth;i++)
{
struct ListNode* p=(struct ListNode*)malloc(sizeof(struct ListNode));
p->data=i;
r->next=p;
r=p;
}
r->next=NULL;
return head;
}
//链表的遍历
void TravelList(struct ListNode* head)
{
struct ListNode* p=head;
while(p!=NULL)
{
printf("%d\n",p->data);
p=p->next;
}
}
//删除第n个节点
struct ListNode* DelNode(struct ListNode* head,int n)
{
int index=0;
struct ListNode* p=head;
//删除第一个节点的情况
if(n==1)
{
struct ListNode* r=p->next;
free(p);
return r;
}
while(p!=NULL)
{
++index;
//删除节点为n时候的情况,需要找到第n个节点的前一个,即n-1
if(index==n-1)
{
struct ListNode* tmp=p->next->next;
free(p->next);
p->next=tmp;
return head;
}
p=p->next;
}
//如果遍历完链表,还是没有找到这个要删除的节点,说明这个节点不在链表中,直接返回原链表
return head;
}
//增加一个节点
struct ListNode* InsertNode(struct ListNode* head,int data,int n)
{
int index=0;
struct ListNode* p=head;
//如果要在第一个节点处增加节点
if(n==1)
{
struct ListNode *new=(struct ListNode*)malloc(sizeof(struct ListNode));
new->data=data;
new->next=p
return new;
}
while(p!=NULL)
{
++index;
if(index==n-1)
{
struct ListNode *new=(struct ListNode*)malloc(sizeof(struct ListNode));
new->next=p->next;
new->data=data;
p->next=new;
return head;
}
p=p->next;
}
return head;
}
//翻转链表
struct ListNode* ReverseList(struct ListNode* head)
{
struct ListNode* p=NULL;
while(head!=NULL)
{
//先保存下一个节点的地址
struct ListNode* tmp=head->next;
//修改当前节点地址为p
head->next=p;
//p指针往前走一个
p=head;
//head指针前移
head=tmp;
//注意head指针在前,p指针在后,最后p和head都指向最后一个节点
}
return p;
}
链表的基本操作就是创建链表,遍历整个链表,增加节点,删除节点,翻转链表这些。
创建链表一般使用的是尾插法,就是始终有一个指针指向新建节点的前一个节点。
链表节点的增加和删除,最重要的就是要找到要增加或删除的这个节点的前一个节点,所以如果要删除第n个节点,那么就需要让索引index=n-1,index要从0开始计数。这里要注意的就是要删除和增加的节点是链表的第一个节点的情况,所以最好单独进行处理。如果再严谨一点,还可以加入对要操作节点的索引的判断,看其是否处于链表当中。
链表的遍历就很容易了,直接从前往后,注意判定条件为p!=NULL。
链表的翻转,很容易。