我在C ++中非常生疏,我正在尝试实现一个双链表,但是我有一些阅读违规并且给出了一些奇怪的值。
#include <iostream>
struct Node
{
int val;
Node* next;
Node* prev;
};
class linkedList
{
public:
linkedList(); //constructor
~linkedList(); //destructor
void push_back(int x);
void addtofront(int x);
//void deleteNode(int x);
bool isempty();
void firstelem();
void prnt_tail();
/*void insert_after(int x, int y);
void insert_before(int x, int y);*/
private:
Node* head;
Node* next;
Node* prev;
};
linkedList::linkedList(){};
linkedList::~linkedList(){};
void linkedList::push_back(int x)
{
linkedList* list = this;
Node temp;
temp.val=x;
temp.next=NULL;
temp.prev=NULL;
if (!head)
{
linkedList* list = new linkedList();
list->head;
head = new Node;
head->val = x;
head->next = NULL;
head->prev = NULL;
}
else
{
Node* temp1;
temp1=head;
while (temp1->next!=NULL)
{
temp1 = temp1->next;
}
temp.next= NULL;
temp.prev=temp1;
temp.val = x;
}
};
void linkedList::addtofront(int x)
{
linkedList* list = this;
Node temp;
temp.val=x;
temp.next=NULL;
temp.prev=NULL;
if (!head)
{
linkedList* list = new linkedList();
list->head;
head = new Node;
head->val = x;
head->next = NULL;
head->prev = NULL;
}
else
{
list->head->prev=&temp;
temp.next=head;
head=&temp;
}
};
//void linkedList::deleteNode(int x)
//{
// if(head)
// {
// linkedList *ptr = head;
// while(ptr->node.val != x)
// {
// ptr = ptr->node.next;
// }
// (ptr->node.next)->prev=ptr->node.prev;
// ptr->node.prev=ptr->node.next;
// delete ptr;
// }
// else
// std::cout<<"empty list";
//}
bool linkedList::isempty()
{
if(head)
return false;
else return true;
};
void linkedList::firstelem()
{
std::cout<<head->val;
};
void linkedList::prnt_tail()
{
if(head)
{
Node *temp;
temp=head;
temp=head->next;
std::cout<<temp;
while(temp->next!=NULL)
{
std::cout<<temp->val<<" ";
}
std::cout<<temp->val;
}
else
{
std::cout<<"empty list";
}
};
//linkedList::insert_after(int x, int y)
//{
//
//}
//
//linkedList::insert_before(int x, int y)
//{
//
//}
和我的主要
#include "linkedlist2.h"
#include <stdlib.h>
#include <iostream>
int main()
{
linkedList example;
if(example.isempty())
std::cout<<"this list is empty "<<"\n";
else
std::cout<<"this list is not empty"<<"\n";
for (int i = 1; i<=20; i++)
{
example.push_back(i);
//example.prnt_tail();
}
example.addtofront(25);
example.firstelem();
std::cout<<"\n";
example.addtofront(28);
example.firstelem();
std::cout<<"\n";
if(example.isempty())
std::cout<<"this list is empty "<<"\n";
else
std::cout<<"this list is not empty"<<"\n";
//example.push_back(26);
//std::cout<<example.head->next->val;
example.firstelem();
std::cout<<"\n";
example.prnt_tail();
std::cout<<"\n";
system("pause");
}
当我运行主要时我得到
此列表为空
-858993460
-858993460
此列表不为空
-858993460
CCCCCCCC
我也得到了错误
访问冲突读取位置0xCCCCCCD0。
并且要执行的下一个语句是“void linkedList :: prnt_tail()”中的while循环
我很确定我的问题出在我的指针中。就像我说的那样,我真的很生疏,所以你能给予的任何帮助都会受到高度赞赏,即使是与我的问题没有直接关系的事情。
答案 0 :(得分:3)
所以,这段代码中存在很多问题。让我们看看我们能做些什么:
您的next
个对象和prev
个对象中都有node
和linkedList
个成员,这很奇怪。让我们通过使linkedList
对象指向第一个节点(即头节点)来解决这个问题,然后使用每个节点中的成员指向下一个对象。
这意味着我们有:
struct Node {
int val;
struct Node* next;
struct Node* prev;
};
class linkedList {
public:
linkedList(); //constructor
~linkedList(); //destructor
void push_back(int x);
void addtofront(int x);
bool isempty();
private:
Node* head;
};
让我们修复push_back中的一些错误。首先,无论LinkedList的状态是什么,我们都需要在堆上创建一个新的Node
,然后我们将Node
放在linkedList中的某个地方。
void linkedList::push_back(int x)
{
Node *node = new Node;
node->next = NULL;
node->prev = NULL;
node->val = x;
if (head == NULL) {
head = node;
} else {
Node *last = head;
while (last->next != NULL)
last = last->next;
last->next = node;
node->prev = last;
}
}
我们还需要修复push_front
。此代码看起来应该与push_back
类似。
void linkedList::addtofront(int x)
{
Node *node = new Node;
node->next = NULL;
node->prev = NULL;
node->val = x;
if (head == NULL) {
head = node;
} else {
node->next = head;
head->prev = node;
head = node;
}
}
如果您要编写构造函数,可能应该正确执行:
linkedList() {
head = NULL;
}
还值得注意的是,您需要一个真正的析构函数来清理您在堆上创建的所有这些对象。然后你还需要实现copy constructor and assignment operator。
答案 1 :(得分:1)
除了额外无用的分号外,这看起来不对:
linkedList::linkedList(){};
构造函数应该为成员提供初始值,而您还没有这样做。让指针成员未初始化是非常糟糕的风格,并且是导致许多问题的原因。
因为这些成员未初始化,所以当您稍后阅读它们时(例如isEmpty()
的测试if (head)
),它将是未定义的行为。
答案 2 :(得分:0)
首先,在addToFront
和push_back
中,您可能不希望在堆上创建新的链接列表。您已经有一个要修改的链表(当前正在运行该方法的链表)。不要在这里创建新的链接列表。
但是,您确实希望在堆上创建新节点,而不是在堆栈上创建新节点。至少在一个地方你在堆栈上创建一个节点,例如
Node temp;
然后存储并使用指向该对象的指针。一旦函数退出,该变量就会消失,指针指向垃圾。
答案 3 :(得分:-1)
在链表类中,(Node * next;)和(Node * prev;)是extera