C++实现单链表的构造

首先,我们需要了解单链表的基本概念。单链表是一种数据结构,它由一系列节点组成,每个节点包含两个部分:数据域和指针域。数据域用于存储节点的数据,指针域则指向下一个节点的地址。单链表的最后一个节点的指针域指向空地址,表示链表的结束。

下面就是C++实现单链表的构造的完整攻略:

  1. 定义节点结构体

首先我们需要定义一个节点的结构体,它包含两个成员,分别是数据域和指针域。具体代码如下所示:

struct Node {
    int data;
    Node* next;
};

其中,int data代表节点的数据,Node* next代表指向下一个节点的指针。

  1. 实现链表的插入操作

链表的插入操作是指向链表中添加一个节点。链表的插入操作分为两种情况,分别是在链表的头部插入节点和在链表的尾部插入节点。具体代码如下所示:

在链表头部插入节点:

void insertNodeAtBeginning(Node* &head, int data) {
    Node* newNode = new Node;
    newNode->data = data;
    newNode->next = head;
    head = newNode;
}

在链表尾部插入节点:

void insertNodeAtEnd(Node* &head, int data) {
    Node* newNode = new Node;
    newNode->data = data;
    newNode->next = nullptr;
    if (head == nullptr) {
        head = newNode;
    } else {
        Node* curr = head;
        while (curr->next != nullptr) {
            curr = curr->next;
        }
        curr->next = newNode;
    }
}

在这里,Node* &head代表链表的头指针。对于在链表头部插入节点的函数void insertNodeAtBeginning(Node* &head, int data)来说,我们需要先申请一个新的节点newNode,将新节点的数据域赋值为要插入的数据,将新节点的指针域指向当前的头结点,并将头指针指向新节点。

对于在链表尾部插入节点的函数void insertNodeAtEnd(Node* &head, int data),我们首先也是需要申请一个新节点newNode,将新节点的数据域赋值为要插入的数据,将新节点的指针域指向空地址,接下来,我们需要判断链表是否为空,如果为空,直接将头指针指向新节点。如果链表不为空,我们需要遍历整个链表,找到最后一个节点,将该节点的指针域指向新节点。

  1. 实现链表的删除操作

链表的删除操作是指从链表中删除一个节点。对于链表的删除操作,我们需要分情况讨论。分为删除头节点、删除尾节点和删除中间节点。具体代码如下所示:

删除头节点:

void deleteNodeAtBeginning(Node* &head) {
    if (head == nullptr) {
        cout << "链表为空,无法进行删除操作" << endl;
        return;
    }
    Node* temp = head;
    head = head->next;
    delete temp;
}

删除尾节点:

void deleteNodeAtEnd(Node* &head) {
    if (head == nullptr) {
        cout << "链表为空,无法进行删除操作" << endl;
        return;
    }
    if (head->next == nullptr) {
        Node* temp = head;
        head = nullptr;
        delete temp;
        return;
    }
    Node* prev = nullptr;
    Node* curr = head;
    while (curr->next != nullptr) {
        prev = curr;
        curr = curr->next;
    }
    prev->next = nullptr;
    delete curr;
}

删除中间节点:

void deleteNode(Node* &head, int data) {
    if (head == nullptr) {
        cout << "链表为空,无法进行删除操作" << endl;
        return;
    }
    Node* prev = nullptr;
    Node* curr = head;
    while (curr != nullptr && curr->data != data) {
        prev = curr;
        curr = curr->next;
    }
    if (curr == nullptr) {
        cout << "需要删除的节点不存在" << endl;
        return;
    }
    if (prev == nullptr) {
        head = curr->next;
    } else {
        prev->next = curr->next;
    }
    delete curr;
}

在这里,对于删除头节点的函数void deleteNodeAtBeginning(Node* &head)来说,我们首先需要判断链表是否为空,如果为空,打印错误信息并直接返回,如果链表不为空,则将头指针指向头节点的下一个节点,并释放头节点所占用的内存。

对于删除尾节点的函数void deleteNodeAtEnd(Node* &head)来说,我们同样需要判断链表是否为空,如果为空则打印错误信息并直接返回。如果链表的长度为1,则将头指针置为空,直接释放头节点所占用的内存。否则,我们需要遍历链表,找到倒数第二个节点,将倒数第二个节点的指针域指向空地址,并释放最后一个节点所占用的内存。

对于删除中间节点的函数void deleteNode(Node* &head, int data)来说,我们需要先遍历链表,找到要删除的节点的前一个节点。如果要删除的节点不存在,则打印错误信息并直接返回。如果要删除的节点是头节点,则需要将头指针指向头节点的下一个节点。如果要删除的节点不是头节点,则需要将要删除的节点的前一个节点的指针域指向要删除的节点的下一个节点,并释放要删除的节点所占用的内存。

  1. 完整代码示例如下所示:
#include <iostream>

using namespace std;

struct Node {
    int data;
    Node* next;
};

void insertNodeAtBeginning(Node* &head, int data) {
    Node* newNode = new Node;
    newNode->data = data;
    newNode->next = head;
    head = newNode;
}

void insertNodeAtEnd(Node* &head, int data) {
    Node* newNode = new Node;
    newNode->data = data;
    newNode->next = nullptr;
    if (head == nullptr) {
        head = newNode;
    } else {
        Node* curr = head;
        while (curr->next != nullptr) {
            curr = curr->next;
        }
        curr->next = newNode;
    }
}

void deleteNodeAtBeginning(Node* &head) {
    if (head == nullptr) {
        cout << "链表为空,无法进行删除操作" << endl;
        return;
    }
    Node* temp = head;
    head = head->next;
    delete temp;
}

void deleteNodeAtEnd(Node* &head) {
    if (head == nullptr) {
        cout << "链表为空,无法进行删除操作" << endl;
        return;
    }
    if (head->next == nullptr) {
        Node* temp = head;
        head = nullptr;
        delete temp;
        return;
    }
    Node* prev = nullptr;
    Node* curr = head;
    while (curr->next != nullptr) {
        prev = curr;
        curr = curr->next;
    }
    prev->next = nullptr;
    delete curr;
}

void deleteNode(Node* &head, int data) {
    if (head == nullptr) {
        cout << "链表为空,无法进行删除操作" << endl;
        return;
    }
    Node* prev = nullptr;
    Node* curr = head;
    while (curr != nullptr && curr->data != data) {
        prev = curr;
        curr = curr->next;
    }
    if (curr == nullptr) {
        cout << "需要删除的节点不存在" << endl;
        return;
    }
    if (prev == nullptr) {
        head = curr->next;
    } else {
        prev->next = curr->next;
    }
    delete curr;
}

int main() {
    Node* head = nullptr;
    insertNodeAtBeginning(head, 3);
    insertNodeAtBeginning(head, 2);
    insertNodeAtBeginning(head, 1);
    insertNodeAtEnd(head, 4);
    deleteNode(head, 3);
    deleteNodeAtBeginning(head);
    deleteNodeAtEnd(head);
    Node* curr = head;
    while (curr != nullptr) {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
    return 0;
}

上面的代码中,我们首先定义了一个头指针Node* head,表示链表的头节点,随后我们向头部插入节点1、2、3,向尾部插入节点4,接下来我们删除了节点3,删除了头节点,并删除了尾节点,最后我们通过遍历链表的方式将链表中的所有节点输出。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++实现单链表的构造 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Jquery给基本控件的取值、赋值示例

    当使用 jQuery 时,我们可以使用 val() 方法来获取或设置表单元素的值。val() 方法适用于 input 元素(不包括 button),select 元素,和 textarea 元素。本文将详细介绍如何使用 jQuery 的 val() 方法来给基本控件取值和赋值。 基本语法 获取值: $("selector").val();…

    other 2023年6月27日
    00
  • 学习JVM之java内存区域与异常

    学习JVM之java内存区域与异常攻略 1. Java内存区域 Java虚拟机(JVM)将内存划分为不同的区域,用于存储不同类型的数据和执行不同的操作。了解这些内存区域对于理解Java程序的内存管理和性能优化至关重要。 1.1 方法区 方法区是JVM中的一块内存区域,用于存储类的结构信息,如类的字段、方法、常量池等。方法区是被所有线程共享的,它在JVM启动时…

    other 2023年8月1日
    00
  • Spring中Properties的配置方式

    Spring中Properties是一种常用的配置方式,可以用于在Spring上下文中配置常量、数据库连接信息等、各种服务的端口等等。下面是关于Spring中Properties的配置方式的详细讲解。 Properties配置方式 定义Properties文件 在Spring中可以定义一个Properties文件来存放各种属性,这个文件可以位于Classpa…

    other 2023年6月25日
    00
  • E语言免杀之易语言程序永久去除_EL_HideOwner

    E语言免杀之易语言程序永久去除_EL_HideOwner攻略 概述 在进行E语言程序开发或分发时,为了保护知识产权和源代码的安全,我们可以使用_EL_HideOwner技术对程序进行免杀处理。本文将详细讲解如何使用_EL_HideOwner去除易语言程序的所有权标记,从而提高程序的安全性。 步骤一:安装_EL_HideOwner插件 首先,我们需要下载并安装…

    other 2023年6月28日
    00
  • PHP对文件夹递归执行chmod命令的方法

    要对文件夹及其子文件夹中的文件进行chmod命令操作,在PHP中可以使用递归函数来实现。下面是PHP对文件夹递归执行chmod命令的方法的攻略: 步骤1:定义递归函数 首先需要定义一个递归函数,用来对传入的目录及其子目录中的文件进行chmod命令操作。下面是一个示例: function chmodDir($dir, $fileMode, $dirMode) …

    other 2023年6月27日
    00
  • jquery 页面滚动到底部自动加载插件集合

    jQuery是一种流行的JavaScript库,它简化了页面编程的复杂性。下面将提供一个完整的攻略指南,描述如何使用jQuery实现Web页面滚动到底部自动加载插件集合。 1. 概述 在Web页面中,当用户滚动到底部时,可以使用jQuery自动加载新内容,从而为用户提供更好的体验。通常,在向远程服务器提出请求之前,需要判断当前页面是否已滚动到页面底部。此时,…

    other 2023年6月25日
    00
  • Win10升级系统后蓝屏或无限重启的解决方法

    Win10升级系统后蓝屏或无限重启的解决方法 问题现象及可能原因 在升级Windows10系统时,有时会出现蓝屏或无限重启的问题,导致系统不能正常使用。可能的原因有多种,例如: 系统升级过程中出现错误导致系统文件损坏 驱动程序不兼容或过期 硬件设备故障等 解决方法 1. 进入安全模式 首先需要进入Windows10的安全模式,通过安全模式来解决蓝屏或无限重启…

    other 2023年6月27日
    00
  • Lua中的模块与module函数详解

    Lua中的模块与module函数详解 在Lua中,模块是一种组织代码的方式,可以将相关的函数、变量和常量封装在一个独立的单元中。模块的使用可以提高代码的可维护性和重用性。Lua提供了module函数来定义和使用模块。 定义模块 要定义一个模块,可以使用module函数。下面是一个简单的示例: — mymodule.lua module(\"mym…

    other 2023年7月29日
    00
合作推广
合作推广
分享本页
返回顶部