我想创建一个单独链接的列表(使用类),在每个列表中都会有:指向文本的指针,指向下一个列表的指针。
我需要实现3个功能:inserts(将列表插入到单链表中,并根据指针指向的文本使用strcmp对元素进行排序)removes(int num),用于删除出现数字的第一个列表。print(),用于打印整个单链表。
我对removes函数有问题,它在运行时会出错,我猜想问题if ( tmp->next == NULL && tmp->number==num ) {
delete tmp;
first = NULL;
}
在哪里,但我不知道为什么会这样。
此外,我不确定我应该如何实现插入函数的排序,所以如果你有任何想法,如果你能解释我在删除函数中的错误,我会非常感激
这是代码:
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
class list
{
private:
int number;
char* word;
list* next;
public:
void inserts(int num, char* text);
void removes(int num);
void print();
};
list* first;
void list::print() {
cout <<"This is our list:"<<endl;
// Temp pointer
list *tmp = first;
// No nodes
if ( tmp == NULL ) {
cout << "EMPTY list" << endl;
return;
}
// One node in the list
if ( tmp->next == NULL ) {
cout <<"NUMBER:t"<< tmp->number;
cout <<"tWORD:t"<< tmp->word << endl;
cout <<"--------------------------------"<<endl;
}
else {
// Parse and print the list
while ( tmp != NULL ){
cout <<"NUMBER:t"<< tmp->number;
cout <<"tWORD:t"<< tmp->word << endl;
cout <<"--------------------------------"<<endl;
tmp = tmp->next;
}
}
}
void list::inserts(int num, char* word){
// Create a new list
list* newlist = new list;
newlist->number=num;
newlist->word=word;
newlist->next=NULL;
// Create a temp pointer
list *tmp = first;
if ( tmp != NULL ) {
// Nodes already present in the list
// Parse to end of list
while ( tmp->next != NULL ) {
tmp = tmp->next;
}
// Point the last node to the new node
tmp->next=newlist;
}
else {
// First node in the list
first = newlist;
}
}
void list::removes(int num){
int k = 0;
list* tmp=first;
if(tmp==NULL)
return;
//Last node of the list
if ( tmp->next == NULL && tmp->number==num ) {
delete tmp;
first = NULL;
}
else {
//Parse thru the nodes
list* prev;
prev = new list;
while ( tmp != NULL )
{
if ( tmp->number == num && k == 0)
first = first->next;
if ( tmp->number == num)
break;
prev = tmp;
tmp = tmp->next;
k++;
}
//Adjust the pointers
prev->next=(tmp->next);
//Delete the current node
delete tmp;
delete prev;
}
}
int main ()
{
first->print();
first->inserts(1200,"endian");
first->print();
/* first->inserts(10,"endianness");
first->inserts(1200,"PEEK");
first->inserts(1200,"POKE");
first->inserts(1200,".MIL");
first->print();*/
first->removes(100);
first->print();
getchar();
}
去掉removes()
函数最后一行中的delete prev;
。
我不是专家,但删除prev会丢失对列表中第一个节点的引用。
顺便说一句,好的评论,让它很容易阅读!
在removes
中,循环while ( tmp != NULL ) { … }
之后,tmp
可能为NULL。
但是,在这个循环之后,你会看到以下几行:
//Adjust the pointers
prev->next=(tmp->next);
您正在取消引用一个NULL指针,这会导致程序崩溃。
将这些行替换为:
//Adjust the pointers
if(tmp)
prev->next=(tmp->next);
还要注意:
removes
例程中的内存管理仍然有一个错误。您永远不会对prev
的初始值调用delete
,并且您会删除在某些情况下应该保留的列表节点。与其做您正在做的事情,不如这样初始化它:list* prev=0;
,然后去掉delete prev
。当这个循环执行时:
while ( tmp != NULL )
tmp指针将到达列表的末尾,当循环中断时将为NULL。
所以,当你执行:
prev->next=(tmp->next);
临时指针没有"next"值。也许您应该在循环之外保留另一个指针。