微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何反转链表中的链接内存链?

如何解决如何反转链表中的链接内存链?

现在,我正在尝试为双向链表编写反向方法。它不仅是从头到尾反转的方法之一,而且特别是列表的一部分,从一个点开始并在开始后的某个点结束。该方法接受名为 ListNodestartPointendPoint 指针引用,它们应该指向链接内存中链的新起点和终点。序列开始前的 nextListNode 成员(所以 startPoint->prev)应该指向新的开始,而 prevListNode 成员应该指向新的开始在序列结束之后(所以 endPoint->next)应该指向新的结束。

我应该指出的一个关键方面是我们可以分配任何新的 ListNodes

在我的 List.h 文件中,我有一个私有类 ListNode。我在 List 类的其余部分提供了它:

template <class T>
class List {
  private:
    class ListNode {
      public:
        ListNode();
        ListNode(const T & ndata);
        ListNode* next;
        ListNode* prev;
        const T data;
    };

  public:
    List();
    List(const List<T>& other);
    List<T>& operator=(const List<T>& rhs);
    int size() const;
    void print(ostream& os = std::cout) const;
    bool empty() const;
    ~List();
    void insertFront(const T& ndata);
    void insertBack(const T& ndata);
    void reverse();
    void tripleRotate();
    List<T> split(int splitPoint);

  private:
    ListNode* head_;
    ListNode* tail_;
    int length_;
    void _copy(const List<T>& other);
    void _destroy();

    /**
     * Helper function to reverse a sequence of linked memory inside a
     * List,starting at startPoint and ending at endPoint. You are
     * responsible for updating startPoint and endPoint to point to the
     * new starting and ending points of the rearranged sequence of
     * linked memory in question.
     *
     * @param startPoint A pointer reference to the first node in the
     *  sequence to be reversed.
     * @param endPoint A pointer reference to the last node in the
     *  sequence to be reversed.
     */
    void reverse(ListNode*& startPoint,ListNode*& endPoint);
};

在我的 List.hpp 文件中,我有反向方法本身。我不知道如何准确地写它。这是我到目前为止所拥有的(显然不起作用):

template <typename T>
void List<T>::reverse(ListNode *& startPoint,ListNode *& endPoint) {
  if (startPoint == endPoint) {
    return;
  }
  //startPoint should point at the new start,endPoint should point at the new end.
  ListNode* current = startPoint;
  ListNode* before_start_point = startPoint->prev;
  ListNode* after_end_point = endPoint->next;
  while (current != after_end_point) {
    ListNode* temp = current->next;
    current->next = current->prev;
    current->prev = temp;
    if (temp == endPoint) {
      endPoint = startPoint;
      startPoint = current;
    }
    current = temp;
  }
}

List.hpp 文件的其余部分:

template <class T>
List<T>::List() { 
    head_ = NULL;
    tail_ = NULL;
    length_ = 0;
}

template <typename T>
void List<T>::_destroy() {
  ListNode* current = head_;
  while (current != NULL) {
    ListNode* temp = current->next;
    delete current;
    current = temp;
  }
}

template <typename T>
void List<T>::insertFront(T const & ndata) {
  ListNode* newNode = new ListNode(ndata);
  //Case where there the list is empty
  if (head_ == NULL) {
    head_ = newNode;
    tail_ = newNode;
    newNode->next = NULL;
    newNode->prev = NULL;
  }
  else {
    newNode->next = head_;
    newNode->prev = NULL;
    head_->prev = newNode;
    head_ = newNode;
  }
  length_++;
}

template <typename T>
void List<T>::insertBack(const T & ndata) {
  ListNode* newNode = new ListNode(ndata);
  if (tail_ == NULL) {
    head_ = newNode;
    tail_ = newNode;
    newNode->next = NULL;
    newNode->prev = NULL;
  }
  else {
    newNode->prev = tail_;
    newNode->next = NULL;
    tail_->next = newNode;
    tail_ = newNode;
  }
  length_++;
}

template <typename T>
typename List<T>::ListNode* List<T>::split(ListNode* start,int splitPoint) {
  //There will be splitPoint number of nodes remaining in the current list
  ListNode* curr = start;
  if (splitPoint == 0) {
    return curr;
  }

  //Takes you to the start of the new list
  for (int i = 0; i < splitPoint && curr != NULL; i++) {
    curr = curr->next;
  }

  if (curr != NULL) {
      curr->prev->next = NULL;
      curr->prev = NULL;
  }

  //Return the head of the new sublist
  return curr;
}

template <typename T>
void List<T>::tripleRotate() {
  if (length_ < 3) {
    return;
  }
  else {
    int third_element_counter = 1;
    bool first_rotation = true;
    int divisible_by_three = length_ % 3;
    ListNode* current = head_;
    while (current != NULL) {
      if (third_element_counter != 3) {
        third_element_counter++;
      }
      else {
        ListNode* first = current->prev->prev;
        ListNode* temp_first_prev = first->prev;
        ListNode* second = current->prev;
        ListNode* temp_current = current;
        ListNode* temp_current_next = current->next; 
        second->prev = temp_first_prev;
        if (temp_first_prev != NULL) {
          temp_first_prev->next = second;
        }
        if (temp_current_next != NULL) {
          temp_current_next->prev = first;
        }
        current->next = first;
        first->next = temp_current_next;
        first->prev = temp_current;
        if (first_rotation) {
          head_ = second;
          first_rotation = false;
        }
        if (divisible_by_three == 0) {
          tail_ = first;
        }
        current = first;
        third_element_counter = 1;
      }
      current = current->next;
    }
  }
}

template <typename T>
void List<T>::reverse() {
  reverse(head_,tail_);
}

感谢任何形式的帮助。

解决方法

根据您的代码,我手动创建了一个包含十个整数的列表:

char *unbase64(const char *input,int length,int *out_len)
{
    BIO *b64,*bmem;
    char *buffer = (char *)malloc(length + 1);
    memset(buffer,length + 1);
    b64 = BIO_new(BIO_f_base64());
    if(b64 == NULL) {
            buffer[0] = '\0';
            return buffer;
    }

    BIO_set_flags(b64,BIO_FLAGS_BASE64_NO_NL);
    bmem = BIO_new_mem_buf((char *)input,length);
    bmem = BIO_push(b64,bmem);
    if((*out_len = BIO_read(bmem,buffer,length)) <= 0) {
            buffer[0] = '\0';
            return buffer;
    }
    buffer[length] = '\0';
    BIO_free_all(bmem);
    return buffer;
}

char * toHex(unsigned char *s) {
    size_t i,len = strlen((const char*)s)*2;
    char *buff = malloc(len + 1);
    if (buff != NULL) {
        for (i = 0; i < len ; i += 2) {
            sprintf(&(buff[i]),"%02x",*s++);
        }
   }
   return buff;
}

int main()
{
  char * b64 = "U2FsdGVkX19+UwN4AAAAALe0aaTselLYGDsTUQk2cSY=";
  int unb64_len = 0;
  char *unb64 = unbase64(b64,strlen((char *)b64),&out_len);
  char * hex_str = toHex(unb64);
  print("hex string: %s\n",hex_str);
  return 1;
 }

然后,我打印了列表:

    List<int> my_list;
    for(int i = 0; i < 10; i++) {
        my_list.insertBack(i);
    }

输出是:

std::cout << "Before reverse:" << std::endl;
    my_list.print();

然后,我运行了一个稍微修改过的反向函数版本:

Before reverse:
Node: 0
Node: 1
Node: 2
Node: 3
Node: 4
Node: 5
Node: 6
Node: 7
Node: 8
Node: 9

并再次打印:

template <typename T>
void List<T>::reverse(ListNode *& startPoint,ListNode *& endPoint) {
  if (startPoint == endPoint) {
    return;
  }

  //startPoint should point at the new start,endPoint should point at the new end.
  ListNode* current = startPoint;
  ListNode* before_start_point = startPoint->prev;
  ListNode* after_end_point = endPoint->next;
  while (current != after_end_point) {
    std::cout << "Working with current node " << current->data << std::endl;
    ListNode* temp = current->next;
    std::cout << "Temp is " << (temp ? temp->data : 0) << std::endl;
    current->next = current->prev;
    std::cout << current->data << "'s new next is now " << (current->next ? current->next->data : 0) << std::endl;
    current->prev = temp;
    std::cout << current->data << "'s new prev is now " << (current->prev ? current->prev->data : 0) << std::endl;

    if (temp == endPoint) {
      endPoint = startPoint;
      startPoint = temp;
    }
    current = temp;
  }
}

输出是:

    std::cout << "After reverse:" << std::endl;
    my_list.print();

所以似乎唯一的问题是在 After reverse: Node: 9 Node: 8 Node: 7 Node: 6 Node: 5 Node: 4 Node: 3 Node: 2 Node: 1 Node: 0 循环末尾的 if 块中,在那里您分配了 while 而它应该是 startPoint = currentstartPoint = endPoint(因为当 startPoint = temp 为真时,if 等于 temp)。

这是完整的代码(也可以在 https://godbolt.org/z/nad7vT 中找到):

endPoint

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。