我在给定链接列表中以相反的顺序创建链接列表时遇到了一些麻烦。
我来自java背景,刚刚开始做一些C ++。
你能看看我的代码,看看有什么问题吗?我猜我只是操纵指针而不是创造任何新东西。
//this is a method of linkedlist class, it creates a reverse linkedlist
//and prints it
void LinkedList::reversedLinkedList()
{
Node* revHead;
//check if the regular list is empty
if(head == NULL)
return;
//else start reversing
Node* current = head;
while(current != NULL)
{
//check if it's the first one being added
if(revHead == NULL)
revHead = current;
else
{
//just insert at the beginning
Node* tempHead = revHead;
current->next = tempHead;
revHead = current;
}
current = current->next;
}//end while
//now print it
cout << "Reversed LinkedList: " << endl;
Node* temp = revHead;
while(temp != NULL)
{
cout << temp->firstName << endl;
cout << temp->lastName << endl;
cout << endl;
temp = temp->next;
}
}//end method
答案 0 :(得分:46)
更简单的一个:浏览链接列表,保存上一个节点和下一个节点,然后让当前节点指向前一个节点:
void LinkedList::reversedLinkedList()
{
if(head == NULL) return;
Node *prev = NULL, *current = NULL, *next = NULL;
current = head;
while(current != NULL){
next = current->next;
current->next = prev;
prev = current;
current = next;
}
// now let the head point at the last node (prev)
head = prev;
}
答案 1 :(得分:4)
Node* revHead;
// ...
while(current != NULL)
{
//check if it's the first one being added
if(revHead == NULL)
您不初始化revHead
但您使用它。
(我希望你已经清楚revHead
是一个用于存储内存地址的局部变量,而不是存在于方法/过程之外的东西)
revHead
的存储类是自动的(也就是在本地范围体中)。在C++
执行此类声明时,无法保证该值为0
。
(除非存储类的类型为static
,或者变量为global
,如果没有提供其他值,它将自动初始化为0
。在您的情况下,变量具有存储类型为auto
的类,这意味着它在函数中是本地定义的,当声明局部变量而没有指定值时,该值是垃圾。请记住,使用下一个C ++标准C++0x
关键字auto
具有新含义)。
您的案例中的值是垃圾,导致if
失败。请在此处查看更多信息:Link
做一个
Node* revHead = NULL;
请记住,您的代码的其他部分可能也会出现类似的错误。
答案 2 :(得分:2)
另一种方法是首先遍历列表并将所有数据存储在堆栈中,然后创建一个新列表并从堆栈顶部插入数据。堆栈为LIFO将以相反的顺序为您提供数据,因此您将有一个反向清单。
答案 3 :(得分:2)
这只使用两个临时变量来完成。
Node* list::rev(Node *first)
{
Node *a = first, *b = first->next;
while(a->next!=NULL)
{
b = a->next;
a->next = a->next->next;
b->next = first;
first = b;
}
return first;
}
此外,您可以使用递归来完成此操作。
答案 4 :(得分:0)
NODE * ReverseLinkedList(NODE * head){
if (head == NULL)
return NULL;
NODE * previous = NULL;
while (head != NULL) {
// Keep next node since we trash the next pointer.
NODE *next = head->pNext;
// Switch the next pointer to point backwards.
head->pNext = previous;
// Move both pointers forward.
previous = head;
head = next;
}
return previous;
}
答案 5 :(得分:0)
我不确定,但我认为你想要一个双向链表,其中节点有下一个和前一个节点。使用指向列表的外部指针不起作用。您将没有上一个节点的地址。
如果不使用上面的方法堆栈,这是一个很好的建议。
答案 6 :(得分:0)
以上是链接列表的反向
void LinkList::rev()
{
if(pFirst == NULL) return;
ListElem *prev = NULL, *current = NULL, *next = NULL;
current = pFirst;
while(current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
// now let the head point at the last node (prev)
pFirst = prev;
}
答案 7 :(得分:0)
下面的示例使用递归来反转链表。我在面试时问了这个问题。这已经过测试和运作。 ListElem是节点。
void LinkList::reverse()
{
if(pFirst == NULL) return;
ListElem* current = pFirst;
revCur(NULL, current, NULL);
}
void LinkList::revCur(ListElem *prev, ListElem* current, ListElem* next)
{
// ListElem *prev = NULL, *current = NULL, *next = NULL;
if ( current != NULL )
{
next = current->next;
current->next = prev;
prev = current;
current = next;
pFirst = prev;
this->revCur(prev,current,next);
}
}
答案 8 :(得分:0)
#include <stdint.h>
/*
this is a generic (structure agnostic) routine for reversing a singly linked list.
1st argument is the memory address the structure is located at, and
2nd argument is the memory address to this particular structure's NEXT member.
*/
void *rsll(void *struct_address, void *next_address /*(void **)*/)
{
uint32_t offset, holder;
offset = next_address - struct_address;
void **p = struct_address, *progress = NULL;
while(p)
{
void *b;
holder = (uint32_t)p;
holder += offset;
p = (void**)holder; //&(N->next)
b = *p; //(N->next)
*p = progress; //(N->next)
holder = (uint32_t)p;
holder -= offset;
p = (void**)holder; //N
progress = p;
p = b;
}
return progress;
}
#include <stdio.h>
int
main()
{
struct list_t
{
int integer;
struct list_t *next;
};
struct list_t d = {40,NULL},
c = {30,&d},
b = {23,&c},
a = {10,&b};
struct list_t *list;
list = &a;
list = rsll(list,&(list->next));
while(list)
{
printf("%d\n",list->integer);
list = list->next;
}
return 0;
}
答案 9 :(得分:0)
我使用类为反向链接列表提供完全可执行的解决方案,因为大多数发现的示例仅使用结构:
#include <iostream>
#include <string>
class listElement
{
std::string data;
listElement* next;
listElement* last; //for doubly linked list
void append(std::string);
void displayElements();
void reverseDisplayElements(listElement*);
listElement* reverseList(listElement*);
public:
listElement() = default;
listElement(std::string newElement)
:data(newElement)
, next(nullptr)
, last(this)
{}
listElement &operator=(const listElement& other) = default;
~listElement();
void setElement(std::string element){append(element);}
void getElements();
void getElementsReverse(listElement* elements);
listElement* setElementsInReverseOrder(listElement* elements);
};
listElement::~listElement()
{
//If the end is not reached, call the method again
if (next != nullptr)
{
next->~listElement();
delete(next);
}
}
void listElement::getElements()
{
std::cout << "\nPrint list:" << std::endl;
displayElements();
}
void listElement::getElementsReverse(listElement *elements)
{
std::cout << "\nJust print the list in reverse order:" << std::endl;
reverseDisplayElements(elements);
}
listElement *listElement::setElementsInReverseOrder(listElement *elements)
{
std::cout << "\n...Reversing elements..." << std::endl;
return reverseList(elements);
}
void listElement::append(std::string newData)
{
// Double linked list
// last->next = new listElement();
// last->next->data = newData;
// last->next->next = nullptr;
// last = last->next;
// Singly linked list
//has next the value nullptr?
//If yes, next pointer
if (next == nullptr)
{
next = new listElement();
next->data = newData;
next->next = nullptr;
}
//else the method again
else
next->append(newData);
}
listElement* listElement::reverseList(listElement* head)
{
//return if no element in list
if(head == nullptr)
return nullptr;
//initialize temp
listElement* temp{};
while(head != nullptr){
listElement* next = head->next;
head->next = temp;
temp = head;
head = next;
}
return temp;
}
void listElement::displayElements()
{
//cout the first entry
std::cout << data << std::endl;
//if the end is not reached, call method next again
if (next != nullptr)
next->displayElements();
}
void listElement::reverseDisplayElements(listElement*head)
{
//recursiv from the last to the list beginning - stop
listElement *temp = head;
if(temp != nullptr)
{
if(temp->next != nullptr)
{
reverseDisplayElements(temp->next);
}
std::cout << temp->data << std::endl;
}
}
int main ()
{
//Pointer to the Beginning of the list
listElement* linkedList = new listElement("Element 1");
//add more elements
linkedList->setElement("Element 2");
linkedList->setElement("Element 3");
linkedList->setElement("Element 4");
linkedList->getElements();
linkedList->getElementsReverse(linkedList);
linkedList->getElements();
linkedList = linkedList->setElementsInReverseOrder(linkedList);
linkedList->getElements();
return 0;
}
我对生产代码的建议是使用
答案 10 :(得分:0)
思路如下:将每个节点移(link)到左边而不是(link)移到右边,但是这里必须考虑特殊的测试用例是代码
void Sll::Myreverse(){
if( length <= 1 )
return;
Node *prev = head , head = head->next ,*next_node = nullptr ;
tail = prev , prev->next = nullptr ;
while( head ){
next_node = curr->next ;
curr->next = prev ;
prev = curr ;
curr = next_node ;
}
head = prev ;
}