问题描述
现在,我正在尝试为双向链表编写反向方法。它不仅是从头到尾反转的方法之一,而且特别是列表的一部分,从一个点开始并在开始后的某个点结束。该方法接受名为 ListNode
和 startPoint
的 endPoint
指针引用,它们应该指向链接内存中链的新起点和终点。序列开始前的 next
的 ListNode
成员(所以 startPoint->prev
)应该指向新的开始,而 prev
的 ListNode
成员应该指向新的开始在序列结束之后(所以 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 = current
或 startPoint = endPoint
(因为当 startPoint = temp
为真时,if
等于 temp
)。
这是完整的代码(也可以在 https://godbolt.org/z/nad7vT 中找到):
endPoint