C++和python实现单链表及其原理

实现单链表及其原理

基本概念

单链表(Singly Linked List)是一种链式存储结构,由一系列节点组成,每个节点包含数据域和一个指向下一个节点的指针域。相比于数组,单链表的插入、删除操作更加方便高效,但是单链表的查询操作效率较低。

C++实现

节点定义

在C++实现中,需要先定义节点(struct Node),包含数据域(data)和指针域(next)。

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

创建操作

创建操作可以分为头插法和尾插法。在头插法中,新节点插入到链表的头部;在尾插法中,新节点插入到链表的尾部。

以头插法为例,具体步骤如下:

  • 创建新节点(newNode);
  • 将newNode的指针域(next)指向原链表的头节点(head);
  • 将头指针(head)指向newNode。
void addNode(Node *&head, int data) {
  Node *newNode = new Node;
  newNode->data = data;
  newNode->next = head;
  head = newNode;
}

查找操作

查找操作可以分为按值查找和按索引查找。按值查找的思路是依次遍历链表的每个节点,直到找到值为目标值的节点。按索引查找的思路是从头节点开始,一直向后遍历指定的次数,直到达到目标节点。

以按值查找为例,具体步骤如下:

  • 从头节点(head)开始遍历链表;
  • 每次遍历时,判断当前节点是否为目标节点,如果是则返回该节点的指针,否则继续遍历;
  • 如果遍历到链表尾部都未找到目标节点,则返回NULL。
Node* searchNode(Node *head, int data) {
  Node *current = head;
  while (current != NULL) {
    if (current->data == data) {
      return current;
    }
    current = current->next;
  }
  return NULL;
}

删除操作

删除操作可以分为按值删除和按索引删除。按值删除的思路是先查找到目标节点,然后将目标节点从链表中删除。按索引删除的思路是先遍历到目标节点的前一个节点,然后将目标节点从链表中删除。

以按值删除为例,具体步骤如下:

  • 先查找到目标节点(targetNode)的前一个节点(preNode);
  • 将preNode的指针域(next)指向targetNode的下一个节点;
  • 释放targetNode的内存。
void deleteNode(Node *&head, int data) {
  Node *preNode = NULL;
  Node *current = head;
  while (current != NULL) {
    if (current->data == data) {
      if (preNode == NULL) {
        head = current->next;
      } else {
        preNode->next = current->next;
      }
      delete current;
      return;
    }
    preNode = current;
    current = current->next;
  }
}

Python实现

节点定义

在Python实现中,需要先定义节点(class Node),包含数据域(data)和指针域(next)。

class Node:
  def __init__(self, data):
    self.data = data
    self.next = None

创建操作

创建操作可以分为头插法和尾插法。与C++实现类似,在头插法中,新节点插入到链表的头部;在尾插法中,新节点插入到链表的尾部。

以尾插法为例,具体步骤如下:

  • 创建新节点(new_node);
  • 遍历链表,找到尾节点;
  • 将尾节点的指针域(next)指向new_node。
def add_node(head, data):
  new_node = Node(data)
  if head is None:
    head = new_node
    return head
  current = head
  while current.next is not None:
    current = current.next
  current.next = new_node
  return head

查找操作

查找操作可以分为按值查找和按索引查找。与C++实现类似,按值查找的思路是依次遍历链表的每个节点,直到找到值为目标值的节点。按索引查找的思路与C++实现类似,不再赘述。

以按值查找为例,具体步骤如下:

  • 从头节点(head)开始遍历链表;
  • 每次遍历时,判断当前节点是否为目标节点,如果是则返回该节点,否则继续遍历;
  • 如果遍历到链表尾部都未找到目标节点,则返回None。
def search_node(head, data):
  current = head
  while current is not None:
    if current.data == data:
      return current
    current = current.next
  return None

删除操作

删除操作可以分为按值删除和按索引删除。与C++实现类似,按值删除的思路是先查找到目标节点,然后将目标节点从链表中删除。按索引删除的思路与C++实现类似,不再赘述。

以按值删除为例,具体步骤如下:

  • 先查找到目标节点(target_node)的前一个节点(pre_node);
  • 将pre_node的指针域(next)指向target_node的下一个节点;
  • 释放target_node的内存。
def delete_node(head, data):
  if head is None:
    return None
  if head.data == data:
    head = head.next
    return head
  pre_node = head
  current = head.next
  while current is not None:
    if current.data == data:
      pre_node.next = current.next
      return head
    pre_node = current
    current = current.next
  return head

示例说明

示例1:C++单链表操作

#include <iostream>
using namespace std;

int main() {
  // 创建头节点
  Node *head = new Node;
  head->data = 1;
  head->next = NULL;

  // 进行添加操作
  addNode(head, 2);
  addNode(head, 3);

  // 进行查找操作
  Node *targetNode = searchNode(head, 2);
  if (targetNode != NULL) {
    cout << "Found the target node, data is " << targetNode->data << endl;
  } else {
    cout << "The target node is not found." << endl;
  }

  // 进行删除操作
  deleteNode(head, 2);

  // 遍历链表
  cout << "The nodes in the linked list: ";
  Node *current = head;
  while (current != NULL) {
    cout << current->data << " ";
    current = current->next;
  }
  cout << endl;

  // 释放内存
  current = head;
  while (current != NULL) {
    Node *temp = current;
    current = current->next;
    delete temp;
  }

  return 0;
}

输出结果为:

Found the target node, data is 2
The nodes in the linked list: 3 1 

示例2:Python单链表操作

# 创建头节点
head = Node(1)

# 进行添加操作
head = add_node(head, 2)
head = add_node(head, 3)

# 进行查找操作
target_node = search_node(head, 2)
if target_node is not None:
  print('Found the target node, data is', target_node.data)
else:
  print('The target node is not found.')

# 进行删除操作
head = delete_node(head, 2)

# 遍历链表
nodes = []
current = head
while current is not None:
  nodes.append(str(current.data))
  current = current.next
print('The nodes in the linked list: ' + ' -> '.join(nodes))

# 释放内存(Python自动管理内存,不需要手动释放)

输出结果为:

Found the target node, data is 2
The nodes in the linked list: 1 -> 3

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

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

相关文章

  • Mapper sql语句字段和实体类属性名字有什么关系

    在Mybatis中,Mapper sql语句中的字段和实体类属性名字是有关联的。这种关系是通过Mybatis中的映射(Mapping)实现的,也就是通过配置xml文件或者注解来指定实体类属性和数据库字段之间的映射关系。 一般地,Mapper sql语句中对应的字段名称应该根据数据库中的字段名来命名,例如表中有id、name、age等字段,则Mapper sq…

    other 2023年6月25日
    00
  • 浅谈Android开发中项目的文件结构及规范化部署建议

    浅谈Android开发中项目的文件结构及规范化部署建议 在Android开发中,良好的项目文件结构和规范化的部署是非常重要的,它们可以提高代码的可读性、可维护性和团队协作效率。本攻略将详细介绍Android项目的文件结构和规范化部署的建议,并提供两个示例说明。 1. 项目文件结构 一个典型的Android项目应该包含以下几个主要目录: app:该目录包含应用…

    other 2023年8月21日
    00
  • 易语言开发ip查看程序教学

    易语言开发IP查看程序教学攻略 本攻略将详细介绍如何使用易语言开发一个IP查看程序。IP查看程序可以用于获取用户的IP地址和相关信息。下面是完整的攻略过程: 步骤一:创建新项目 打开易语言开发环境。 点击“新建”按钮,创建一个新项目。 在弹出的对话框中,选择“窗体应用程序”作为项目类型,并设置项目名称。 点击“确定”按钮,创建新项目。 步骤二:设计用户界面 …

    other 2023年7月31日
    00
  • Android实现动态定值范围效果的控件

    当在Android应用中实现动态定值范围效果的控件时,可以按照以下攻略进行操作: 1. 创建自定义控件 首先,您需要创建一个自定义控件来实现动态定值范围效果。您可以继承现有的控件类(如SeekBar)或创建一个全新的自定义控件类。以下是一个示例: public class RangeSeekBar extends SeekBar { private int …

    other 2023年10月12日
    00
  • 微软Win11 Build 2262x.1537预览版发布(附KB5022910更新内容汇总)

    微软Win11 Build 2262x.1537预览版发布攻略 微软最新发布了Win11 Build 2262x.1537预览版,本攻略将详细介绍如何安装和更新该版本,并附带了KB5022910更新内容的汇总。 步骤1:下载Win11 Build 2262x.1537预览版 首先,你需要下载Win11 Build 2262x.1537预览版的安装文件。你可以…

    other 2023年8月3日
    00
  • 7——使用textview实现跑马灯

    7——使用TextView实现跑马灯 在Android应用的开发中,使用跑马灯效果可以给用户带来视觉上的特殊体验,增加应用的吸引力。在Android中,我们可以使用TextView实现跑马灯效果。 基本实现 使用TextView实现跑马灯效果非常简单。我们只需要在布局文件中添加TextView,并设置相关属性即可。以下是实现跑马灯效果的示例代码: <T…

    其他 2023年3月28日
    00
  • JS全局变量和局部变量最新解析

    JS全局变量和局部变量最新解析攻略 在JavaScript中,变量的作用域分为全局作用域和局部作用域。全局变量在整个程序中都可访问,而局部变量只在定义它们的函数内部可访问。本攻略将详细解释全局变量和局部变量的概念、作用域以及它们的最新解析。 全局变量 全局变量是在程序的顶层定义的变量,可以在整个程序中的任何地方访问。它们在全局作用域中声明,因此在任何函数内部…

    other 2023年7月29日
    00
  • Linux lseek函数的使用详解

    Linux lseek函数的使用详解 在Linux系统中,lseek函数用于重新定位文件读写指针的位置。该函数能够使程序能够访问文件中不同的位置。本文将详细介绍lseek函数的使用方法和示例。 函数原型 在C语言头文件<unistd.h>中,可以找到lseek函数的原型: #include <unistd.h> off_t lseek…

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