C语言链表的基本操作—建表,遍历,增加,删除,翻转


#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。

链表的翻转,很容易。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值