C语言链表实现

2023-12-19 21:51:12

链表实现的逻辑

链表,本质是结构体,包含了节点值和后节点指针两个数据(双向链表会有两个节点指针)

struct LIST{
    int data;
    struct LIST* next;
};
//创建了struct LIST结构体

基本操作的代码实现

插入
struct LIST* listInsert(struct LIST *head,int data,int n){//在索引为i的节点插入新节点(初始索引为0)
    struct LIST *temp1=(struct LIST*)malloc(sizeof(struct LIST));//创建新节点
    temp1->data=data;
    temp1->next=NULL;
    if(n==0){//头插入
        temp1->next=head;
        head=temp1;
        return head;
    }
    struct LIST *temp2=head;//遍历到目标节点的前节点
    for(int i=0;i<n-1;i++){
        temp2=temp2->next;
    }
    temp1->next=temp2->next;//新节点指向目标节点
    temp2->next=temp1;//前节点指向新节点
    return head;//更新头节点
}
删除
struct LIST* listDelete(struct LIST *head,int target){//删除节点值为target的节点
    if(target==head->data){//只有一个节点
        head=NULL;
        return head;
    }
    struct LIST *temp1=head;
    while((temp1->next)->data!=target){
        temp1=temp1->next;//遍历到目标节点的前节点
    }
    struct LIST *temp2=temp1->next;//temp2为目标节点
    temp1->next=temp2->next;
    temp2->next=NULL;
    return head;
}
打印
void printList(struct LIST *head){//打印链表
    struct LIST *temp=head;
    printf("list is:");
    while(temp!=NULL){//遍历所有节点并打印
        printf("%d ",temp->data);
        temp=temp->next;
    }
    printf("\n");
}
释放空间
void listFree(struct LIST *head){//释放空间
    if(head){
        //递归free空间
        struct LIST *temp=head->next;
        free(head);
        listFree(temp);
    }
}
求长度
int listLength(struct LIST *head){//得到链表长度
    if(head) return listLength(head->next)+1;
}
寻找节点
struct LIST* listFind(struct LIST *head,int target){//找到data为target的节点
    while(head->data!=target){
        head=head->next;//未找到,不断后移节点
    }
    return head;   
}
反转链表
struct LIST* listReverse(struct LIST *head){//反转链表
    if(!head->next){//一个节点
        return head;
    }
    else if(!(head->next)->next){//两个节点
        (head->next)->next=head;
        head->next=NULL;
        return head;
    }
    struct LIST* temp1=head;//前节点
    struct LIST* temp2=head->next;//中间节点
    struct LIST* temp3=temp2->next;//后节点
    while(temp3!=NULL){//中节点为最后有效节点
        temp2->next=temp1;//中节点指向前节点
        temp1=temp2;//前节点后移
        temp2=temp3;//中节点后移
        temp3=temp3->next;//后节点但后移
    }
    temp2->next=temp1;//最后有效节点处理
    head->next=NULL;//头节点指向NULL
    head=temp2;//头节点变换为尾节点
    return head;//返回新的头节点
}

易错点

每次操作完,必须更新头节点,因为头节点指向内容虽然改变,但是头节点本身地址并没有改变,

除非使用

struct LIST **head_ref;
//创建头节点指针的指针

这样就不需要显式地更新头节点

文章来源:https://blog.csdn.net/Xudong_12345/article/details/135094330
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。