C++ 实现单链表的基本操作

发布于:2025-04-18 ⋅ 阅读:(76) ⋅ 点赞:(0)

概述

单链表是最基本的数据结构之一,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。单链表的特点是动态存储和灵活的元素插入、删除操作。本文将通过 C++ 实现单链表的基本操作:创建、查询、插入、删除、头插、尾插、打印等,帮助大家了解如何在 C++ 中实现和操作链表。

链表节点结构

在 C++ 中,链表的基本单元是节点(Node)。每个节点包含两个部分:

  • data:节点存储的数据。

  • next:指向下一个节点的指针。

我们定义一个结构体 LNode 来表示链表的节点:

typedef int Datatype;
typedef struct LNode {
    Datatype data;
    struct LNode* next;
} Node, *Linklist;

链表的创建

我们可以通过头插法来创建链表。头插法是将新的节点插入到链表的头部,即将新节点的 next 指针指向当前的头节点,然后更新头节点为新节点。

Linklist CreateList(Linklist& L, int n) {
    L = (Linklist)malloc(sizeof(Node));  // 创建一个新的头节点
    L->next = NULL;  // 初始化头节点的 next 为 NULL

    for (int i = 0; i < n; i++) {
        Linklist p = (Linklist)malloc(sizeof(Node));  // 创建新节点
        scanf("%d", &p->data);  // 输入数据
        p->next = L->next;  // 将新节点的 next 指向当前头节点
        L->next = p;  // 更新头节点
    }
    return L;
}

链表的插入操作

链表的插入操作可以在指定的位置插入一个新节点。在 InsertList 函数中,我们首先找到插入位置的前一个节点 p,然后创建新节点 q,将 p->next 指向 qq->next 指向原来的节点。

int InsertList(Linklist& L, int i, Datatype& e) {
    Linklist p = L;
    int j = 0;
    while (p && j < i - 1) {
        p = p->next;
        j++;
    }
    if (!p || j > i)
        return ERROR;
    Linklist q = (Linklist)malloc(sizeof(Node));
    q->data = e;
    q->next = p->next; 
    p->next = q;
    return OK;
}

链表的删除操作

删除操作的基本思想是:找到待删除节点的前一个节点 p,然后将 p->next 指向待删除节点的下一个节点。删除操作之后需要释放被删除节点的内存。

int DeleteList(Linklist& L, int i, Datatype& e) {
    Linklist p = L;
    int j = 0;
    while (p && j < i - 1) {
        p = p->next;
        j++;
    }
    if (!p || j > i)
        return ERROR;
    Linklist q = p->next;
    p->next = q->next;
    e = q->data;
    free(q);
    return OK;
}

查询操作

查询操作是根据给定的值在链表中查找元素。如果找到该元素,返回其在链表中的位置;如果找不到,返回 0。

int LocateElem(Linklist& L, Datatype e) {
    Linklist p = L->next;
    int i = 1;
    while (p && p->data != e) {
        p = p->next;
        i++;
    }
    if (!p)
        return 0;
    return i;
}

头插与尾插操作

  • 头插法:每次插入的新节点都会插入到链表的头部,更新头节点的指针。

void insert_front(Linklist& L, Datatype e) {
    Linklist p = (Linklist)malloc(sizeof(Node));
    p->data = e;
    p->next = L->next;
    L->next = p;
}
  • 尾插法:每次插入的新节点都会插入到链表的尾部。我们首先找到链表的最后一个节点,再将新节点插入。

void insert_back(Linklist& L, Datatype e) {
    Linklist p = L;
    while (p->next != NULL) {
        p = p->next;
    }
    Linklist q = (Linklist)malloc(sizeof(Node));
    q->data = e;
    q->next = NULL;
    p->next = q;
}

打印链表

打印链表的操作是遍历链表并输出每个节点的数据。

void PrintList(Linklist& L) {
    Linklist p = L->next;
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

主函数与菜单

主函数中实现了一个简单的菜单,用户可以选择执行链表的各种操作:新建链表、查询、插入、删除、打印、头插、尾插和退出。

int main() {
    Linklist L = NULL;
    cout << "------------------单链表基本操作------------------" << endl;
    cout << "1.新建    2.查询    3.插入    4.删除    5.打印    6.头插    7.尾插    8.退出" << endl;

    int n;
    while (true) {
        cout << "请选择操作: ";
        scanf("%d", &n);

        switch (n) {
        case 1: {
            cout << "请输入链表长度:";
            int m;
            scanf("%d", &m);
            CreateList(L, m);
            cout << "创建成功!" << endl;
            break;
        }
        case 2: {
            cout << "请输入要查询的元素:";
            int e;
            scanf("%d", &e);
            int m = LocateElem(L, e);
            if (m == 0) {
                cout << "未找到该元素!" << endl;
            }
            else {
                cout << "该元素在第" << m << "个位置!" << endl;
            }
            break;
        }
        case 3: {
            cout << "请输入要插入的位置和元素:";
            int i, e;
            scanf("%d%d", &i, &e);
            if (InsertList(L, i, e) == OK) {
                cout << "插入成功!" << endl;
            }
            else {
                cout << "插入失败!" << endl;
            }
            break;
        }
        case 4: {
            cout << "请输入要删除的位置:";
            int i;
            scanf("%d", &i);
            int e;
            if (DeleteList(L, i, e) == OK) {
                cout << "删除成功!删除的元素为:" << e << endl;
            }
            else {
                cout << "删除失败!" << endl;
            }
            break;
        }
        case 5:
            PrintList(L);
            break;
        case 6: {
            cout << "请输入要插入的元素:";
            int e;
            scanf("%d", &e);
            insert_front(L, e);
            cout << "头插成功!" << endl;
            break;
        }
        case 7: {
            cout << "请输入要插入的元素:";
            int e;
            scanf("%d", &e);
            insert_back(L, e);
            cout << "尾插成功!" << endl;
            break;
        }
        case 8:
            return 0;
        default:
            cout << "请输入正确的操作!" << endl;
        }
    }

    return 0;
}

总结

通过本文的实现,我们学习了如何使用 C++ 实现单链表的基本操作。链表是一个非常灵活的数据结构,支持高效的插入和删除操作。希望通过这篇文章,大家能够更深入理解链表的工作原理,并能够根据实际需求进行修改和优化。


网站公告

今日签到

点亮在社区的每一天
去签到