无头节点单链表基本操作(头插、尾插、删除)————附完整代码

0 背景

一般使用单链表多使用带头节点的单链表,好处是:

  • 1 对表首操作和在表的其他位置的操作一致,无需特殊处理;
  • 2 判链表是否为空时,头指针都是指向头节点的非空指针,空表和非空表的处理也得到统一。【如果不带头节点时,空链表的头指针为NULL】

1 创建链表操作

存储结构定义:

typedef struct LNode{
    int data;//数据
    struct LNode* next;//指针域
}LNode;

1.1 头插法

//头插法
LNode* List_Head(LNode* &L, int x){
    LNode* s;
    s = (LNode*) malloc(sizeof(LNode));
    s->data = x;
    s->next = L;
    L = s;//把新节点的地址赋给头指针
    return s;
}
//创建头指针
    LNode* L = (LNode*)malloc(sizeof(LNode));
    /*
     * 头插法
     */
     //第一个数据赋值
    L->data = 2;
    L->next = NULL;
    //

1.2 尾插法

//尾插法
LNode* List_Tail(LNode* &r, int x){
    LNode *s;
    s = (LNode*)malloc(sizeof(LNode));
    s->data = x;
    r->next = s;
    r = s;
    r->next = NULL;
    return r;
}
    //创建头指针
    LNode* L = (LNode*)malloc(sizeof(LNode));
     /*
     * 尾插法
     */
    //第一个数据赋值
    L->data = 2;
    L->next = NULL;
    LNode* r = L;//表尾指针
    

2 删除元素

//删除值为x的节点,L为头指针
void List_Erase(LNode* &L, int x){
    LNode* p;
    if(L == NULL) return;
    if(L->data == x){
        p = L;
        L = L->next;
        /*
        使原本指向当前结点的指针指向下一个结点【等价于L->next = L->next->next】,
        因此下面的语言不会断链
        */
        free(p);
        List_Erase(L, x);
    }else{
        List_Erase(L->next, x);
    }
}

3 完整示例

#include <cstdio>
#include <cstdlib>

typedef struct LNode{
    int data;//数据
    struct LNode* next;//指针域
}LNode;
//尾插法
LNode* List_Tail(LNode* &r, int x){
    LNode *s;
    s = (LNode*)malloc(sizeof(LNode));
    s->data = x;
    r->next = s;
    r = s;
    r->next = NULL;
    return r;
}
//头插法
LNode* List_Head(LNode* &L, int x){
    LNode* s;
    s = (LNode*) malloc(sizeof(LNode));
    s->data = x;
    s->next = L;
    L = s;
    return s;
}
//删除值为x的节点
void List_Erase(LNode* &L, int x){
    LNode* p;
    if(L == NULL) return;
    if(L->data == x){
        p = L;
        L = L->next;
        free(p);
        List_Erase(L, x);
    }else{
        List_Erase(L->next, x);
    }
}

int main(){
    //创建头指针
    LNode* L = (LNode*)malloc(sizeof(LNode));
    /*
     * 头插法
     */
    L->data = 2;
    L->next = NULL;
    List_Head(L, 5);
    List_Head(L, 2);
    List_Head(L, 4);
    List_Head(L, 3);
    List_Head(L, 2);
    List_Head(L, 1);
    List_Head(L, 2);
    /*
     * 尾插法
     */
//    L->data = 2;
//    L->next = NULL;
//    LNode* r = L;//表尾指针
//    List_Tail(r, 1);
//    List_Tail(r, 2);
//    List_Tail(r, 3);
//    List_Tail(r, 4);
//    List_Tail(r, 2);
//    List_Tail(r, 5);
//    List_Tail(r, 2);
    //判空链表
  //  L->data = 2;
    //L->next = NULL;

    /*
     * 删除元素值为2
     */
    List_Erase(L, 2);
    /*
     * 打印链表
     */
    while(L != NULL){
        printf("%d ", L->data);
        L = L->next;
    }

    return 0;
}

结果:
在这里插入图片描述

数据结构中的循环单链表是一种特殊的链表,其中节点的next指针指向节点,而节点的next指针又指向节点,形成了一个环形结构。法(pushing at the end)是向循环链表中添加新节点的一种常见方法,通常在链表为空或已知节点的情况下操作。 下面是一个使用C语言实现循环单链表法的简单代码示例: ```c #include <stdio.h> #include <stdlib.h> // 定义链表节点结构体 typedef struct Node { int data; // 数据域 struct Node* next; // 指向下一个节点的指针 } Node; // 初始化链表为循环链表 Node* createCircularList() { Node* head = NULL; return head; } // 法添加新节点 void insertAtEnd(Node** head, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); if (!newNode) { printf("Memory allocation failed.\n"); return; } newNode->data = data; newNode->next = *head; if (*head == newNode) { newNode->next = newNode; // 如果链表为空,形成环 } else { for (Node* current = *head; current->next != *head; current = current->next) { // 遍历直到找到节点 } current->next = newNode; } // 更新节点 *head = newNode; } // 打印循环链表 void printCircularList(Node* head) { if (head == NULL) { printf("Empty list.\n"); return; } Node* current = head; do { printf("%d ", current->data); current = current->next; } while (current != head); printf("\n"); } int main() { Node* head = createCircularList(); insertAtEnd(&head, 1); insertAtEnd(&head, 2); insertAtEnd(&head, 3); printf("Circular linked list after insertion:\n"); printCircularList(head); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星蓝雨

如果觉得文章不错,可以请喝咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值