单链表(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;
}
posted @ 2023-05-30 21:48  hacker_dvd  阅读(21)  评论(0)    收藏  举报