首页 > 编程语言 >单链表(c++实现)

单链表(c++实现)

时间:2023-05-30 21:55:16浏览次数:46  
标签:getNext LinkList head 单链 ListNode 实现 value current c++

template<typename T>
class ListNode {
 public:
  explicit ListNode(T value_, ListNode* next_ = nullptr) : value(value_), next(next_) {}
  T getValue() const { return value; }
  ListNode<T>* getNext() const {return next;};
  void setNext(ListNode<T>* next_) { next = next_; }
 private:
  T value;
  ListNode<T>* next;
};

template<typename T>
class LinkList {
 public:
  LinkList() : head(nullptr), tail(nullptr), size(0) {}
  LinkList(LinkList &&) noexcept = default;
  LinkList(const LinkList &) = default;
  LinkList &operator=(LinkList &&) noexcept = default;
  LinkList &operator=(const LinkList &) = default;
  ~LinkList();

  // 头插法
  ListNode<T>* addToHead(T value);
  // 尾插法
  ListNode<T>* addToTail(T value);
  // 在下标为 idx 后插入
  ListNode<T>* addByIndex(unsigned idx, T value);
  // 按值寻找
  ListNode<T>* findByValue(T value) const;
  // 按下标寻找
  ListNode<T>* findByindex(unsigned idx) const;
  // 按值删除
  bool removeByValue(T value);
  // 按下标删除
  bool removeByindex(unsigned idx);
  // 打印输出
  void printLinkList();
private:
  ListNode<T>* head;
  ListNode<T>* tail;
  unsigned size;
};

template<typename T>
LinkList<T>::~LinkList() {
  auto current = head;
  while (current != nullptr) {
    auto nextNode = current->getNext();
    delete current;
    current = nextNode;
  }
}

template<typename T>
ListNode<T>* LinkList<T>::addToHead(T value) {
  auto newNode = new ListNode<T>(value, head);
  head = newNode;
  if (tail == nullptr) {
    tail = newNode;
  }
  ++size;
  return newNode;
}

template<typename T>
ListNode<T>* LinkList<T>::addToTail(T value) {
  auto newNode = new ListNode<T>(value);
  if (tail != nullptr) {
    tail->setNext(newNode);
  } else {
    head = newNode;
  }
  tail = newNode;
  ++size;
  return newNode;
}

template<typename T>
ListNode<T>* LinkList<T>::addByIndex(unsigned int idx, T value) {
  if (idx > size) {
    std::cout << "fail to addByIndex" << std::endl;
    return nullptr;
  }
  if (idx == 0) {
    addToHead(value);
  } else if (idx == size) {
    addToTail(value);
  } else {
    auto current = head;
    for (int i = 0; i < idx - 1; i++) {
      current = current->getNext();
    }
    auto newNode = new ListNode<T>(value);
    newNode->setNext(current->getNext());
    current->setNext(newNode);
    ++size;
    return newNode;
  }
}

template<typename T>
ListNode<T>* LinkList<T>::findByValue(T value) const {
  auto current = head;
  while (current != nullptr) {
    if (current->getValue() == value) {
      return current;
    }
    current = current->getNext();
  }
  return nullptr;
}

template<typename T>
ListNode<T>* LinkList<T>::findByindex(unsigned idx) const {
  if (idx >= size) {
    return nullptr;
  }
  auto current = head;
  for (int i = 0; i < idx; i++) {
    current = current->getNext();
  }
  return current;
}

template<typename T>
bool LinkList<T>::removeByValue(T value) {
  if (head == nullptr) {
    return false;
  }

  if (head->getValue() == value) {
    auto newHead = head->getNext();
    delete head;
    head = newHead;
    if (head == nullptr) {
      tail = nullptr;
    }
    --size;
    return true;
  }

  auto current = head;
  while (current->getNext() != nullptr) {
    if (current->getNext()->getValue() == value) {
      auto nodeToRemove = current->getNext();
      current->setNext(nodeToRemove->getNext());
      if (nodeToRemove == tail) {
        tail = current;
      }
      delete nodeToRemove;
      --size;
      return true;
    }
    current = current->getNext();
  }

  return false;
}

template<typename T>
bool LinkList<T>::removeByindex(unsigned int idx) {
  if (idx >= size) {
    return false;
  }
  if (idx == 0) {
    auto newHead = head->getNext();
    delete head;
    head = newHead;
    if (head == nullptr) {
      tail = nullptr;
    }
    --size;
    return true;
  }

  auto current = head;
  for (int i = 0; i < idx - 1; i++) {
    current = current->getNext();
  }
  auto nodeToRemove = current->getNext();
  current->setNext(nodeToRemove->getNext());
  if (nodeToRemove == tail) {
    tail = current;
  }
  delete nodeToRemove;
  --size;
  return true;
}

template<typename T>
void LinkList<T>::printLinkList() {
  auto current = head;
  while (current != nullptr) {
    std::cout << current->getValue() << " ";
    current = current->getNext();
  }
  std::cout << std::endl;
}

标签:getNext,LinkList,head,单链,ListNode,实现,value,current,c++
From: https://www.cnblogs.com/hacker-dvd/p/17444591.html

相关文章

  • linux 中sed命令实现文本的大小写转换
     001、将所有的小写字母转换为大写[root@PC1test4]#lsa.txt[root@PC1test4]#cata.txt##测试数据abdmnjuyrXDETHRQYEcvbDdggyi[root@PC1test4]#sed's/[a-z]/\U&/g'a.txt##所有小写字母转换为大写ABDMNJUYRXDETHRQYECVB......
  • 如何选择软件快速开发平台,让办公实现自动化发展?
    如果要实现办公自动化发展,软件快速开发平台是理想的助力能手。随着智能化、数字化的快速发展,在众多中大型企业中,低代码开发平台的应用价值逐渐攀升。不仅因为它的实用性和适用性,而且还因为它的灵活性、易操作等特性,使其在办公自动化发展中作用凸显,深得人心。那么,作为企业,应该如何......
  • 内存泄漏、缓存溢出?C和C++,哪个更懂得管理内存质量?
    一、c/c++程序内存区域划分c和c++的内存区域划分是十分相似的,因为c++是完全兼容c语言,是c语言的面向对象的升级版。接下来看如下图:程序的内存区域被划分成6个区域。内核空间、栈、内存映射段、堆、数据段、代码段。下面是对相关内存区域名词解释:栈又叫堆栈--非静态局部变量/函数参数......
  • 单链表
    1、特点:任意存储,顺序存取2、结构体定义和预定义#include<stdio.h>#include<stdlib.h>//malloc函数#defineElemTypeint#defineStatusint#defineERROR0#defineOK1typedefstructLnode{ElemTypedata;structLnode*next;}Lnode,*Linklist;3、初始......
  • 在树莓派上实现numpy的conv2d卷积神经网络做图像分类,加载pytorch的模型参数,推理mnist
    这几天又在玩树莓派,先是搞了个物联网,又在尝试在树莓派上搞一些简单的神经网络,这次搞得是卷积识别mnist手写数字识别训练代码在电脑上,cpu就能训练,很快的:importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorchvisionimportdatasets,transformsimportn......
  • 为什么 C++ 有指针了还要引用
    引用传递,只是明面上,没有使用值传递,值传递本身是不可避免的。编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递。所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。别名,可不是真实的数据类型。因为,函数传递参数需要,数据复制,......
  • 【无人机三维路径规划】基于蚁群算法实现无人机三维路径规划含Matlab代码
    ⛄内容介绍随着无人机可执行任务的多样化,航迹规划成为其顺利完成任务的基本前提。针对该问题,提出了基于蚁群算法的无人机航迹规划方法。运用等效地形模拟方法,将作战区域中的敌方威胁、地形障碍等效为山峰,构建了无人机航迹规划的场景。以此为基础,采用抽象蚁群,对起始点和终点已知的......
  • nginx实现负载均衡实例
    好的,这里提供一个简单的Nginx负载均衡配置示例,来说明其功能和配置方法。假设您有多个Web服务器提供相同的服务,您可以通过Nginx实现负载均衡以分担流量和请求压力。首先安装并启动Nginx。配置Nginx的负载均衡策略。在Nginx的主配置文件中(通常是/etc/nginx/nginx.conf......
  • RocketMQ 多级存储设计与实现
    作者:张森泽随着RocketMQ5.1.0的正式发布,多级存储作为RocketMQ一个新的独立模块到达了TechnicalPreview里程碑:允许用户将消息从本地磁盘卸载到其他更便宜的存储介质,可以用较低的成本延长消息保留时间。本文详细介绍RocketMQ多级存储设计与实现。设计总览RocketMQ多级......
  • 三方仓库如何实现Zadig流水线自动触发
    !!大家好,我是乔克,一个爱折腾的运维工程,一个睡觉都被自己丑醒的云原生爱好者。作者:乔克公众号:运维开发故事博客:www.jokerbai.com最近因为公司的产研调整,决定将代码仓库从本地的Gitlab迁移到云效的Codeup,不是Gitlab不够好,而是Codeup在度量、安全等方面比原生的Gitlab要好,再......