2

亲爱的大家;

嗨,我只是 C++ 的初学者;请帮助我理解:

链表类中应该有哪些功能?我认为应该有重载的运算符 << 和 >>; 请帮助我改进代码(样式、错误等) 感谢您的提前。伊格尔。

编辑:这只是第一阶段,下一个阶段将(希望)带有模板。

请查看整数列表的小代码(包含 MyNODE.h 和 ListDriver1.cpp);我的节点.h

    // This is my first attempt to write linked list. Igal Spector, June 2010.

#include <iostream.h>
#include <assert.h>

//Forward Declaration of the classes:
class ListNode;
class TheLinkedlist;

// Definition of the node (WITH IMPLEMENTATION !!!, without test drive):


class ListNode{
 friend class TheLinkedlist;
public:
 // constructor:
 ListNode(const int& value, ListNode *next= 0);
 // note: no destructor, as this handled by TheLinkedList class.

 // accessor: return data in the node.
// int Show() const {return theData;}

private:
 int theData;  //the Data
 ListNode* theNext; //points to the next node in the list.
};

//Implementations:
//constructor:
inline ListNode::ListNode(const int &value,ListNode *next)
:theData(value),theNext(next){}


//end of ListNode class, now for the LL class:

class TheLinkedlist
{
public:
 //constructors:
 TheLinkedlist();
 virtual ~TheLinkedlist();
 // Accessors:
 void InsertAtFront(const &);
 void AppendAtBack(const &);

// void InOrderInsert(const &);
 bool IsEmpty()const;//predicate function
 void Print() const;
private:
 ListNode * Head; //pointer to first node
 ListNode * Tail; //pointer to last node.
};

//Implementation:

//Default constructor
inline TheLinkedlist::TheLinkedlist():Head(0),Tail(0) {}

//Destructor
inline TheLinkedlist::~TheLinkedlist(){
 if(!IsEmpty()){  //list is not empty
 cout<<"\n\tDestroying Nodes"<<endl;
 ListNode *currentPointer=Head, *tempPtr;

  while(currentPointer != 0){ //Delete remaining Nodes.
   tempPtr=currentPointer;
  cout<<"The node: "<<tempPtr->theData <<" is Destroyed."<<endl<<endl;
  currentPointer=currentPointer->theNext;
  delete tempPtr;
  }
 Head=Tail = 0;  //don't forget this, as it may be checked one day.
 }
}

//Insert the Node to the beginning of the list:
void TheLinkedlist::InsertAtFront(const int& value){
 ListNode *newPtr = new ListNode(value,Head);
 assert(newPtr!=0);

 if(IsEmpty())  //list is empty
  Head = Tail = newPtr;
 else {    //list is NOT empty
  newPtr->theNext = Head;
  Head = newPtr;
 }
}

//Insert the Node to the beginning of the list:
void TheLinkedlist::AppendAtBack(const int& value){
 ListNode *newPtr = new ListNode(value, NULL);
 assert(newPtr!=0);

 if(IsEmpty())  //list is empty
  Head = Tail = newPtr;
 else {    //list is NOT empty
  Tail->theNext = newPtr;
  Tail = newPtr;
 }
}

//is the list empty?
inline bool TheLinkedlist::IsEmpty() const
  { return (Head == 0); }

// Display the contents of the list
void TheLinkedlist::Print()const{
 if ( IsEmpty() ){
  cout << "\n\t The list is empty!!"<<endl;
  return;
 }

 ListNode *tempPTR = Head;
 cout<<"\n\t The List is: ";

 while ( tempPTR != 0 ){
  cout<< tempPTR->theData <<"  ";
  tempPTR = tempPTR->theNext;
 }
 cout<<endl<<endl;
}
//////////////////////////////////////

测试驱动程序:

//Driver test for integer Linked List.

#include <iostream.h>
#include "MyNODE.h"

// main Driver
int main(){

 cout<< "\n\t This is the test for integer LinkedList."<<endl;

 const int arraySize=11,
   ARRAY[arraySize]={44,77,88,99,11,2,22,204,50,58,12};

 cout << "\n\tThe array is: "; //print the numbers.
 for (int i=0;i<arraySize; i++)
  cout<<ARRAY[i]<<",  ";

 TheLinkedlist list;   //declare the list

 for(int index=0;index<arraySize;index++)
  list.AppendAtBack( ARRAY[index] );//create the list

 cout<<endl<<endl;
 list.Print();    //print the list

 return 0;     //end of the program.
}
4

2 回答 2

7

链表类中应该有哪些功能?

这取决于你需要用它做什么。至少,应该能够向其中添加元素,并查看列表中的元素。

(这是常识。因为如果你不能以任何方式修改或阅读你的列表,它还能用来做什么?)


我认为应该有重载的运算符 << 和 >>;

为什么?他们会怎么做?我想您的意思是operator <<进行插入,类似于将对象插入到 C++ IO 流中的方式;但究竟应该operator >>怎么做?提取/删除某种元素?如果您以这种方式实现插入和提取(?),可能没有人能够理解您的链表类。链表不是IO 流。(为简洁起见,选择了那些具有 IO 流的运算符。)

如果操作的含义不明确,我会建议您不要使用运算符重载。我建议您更明确地命名您的操作,例如通过提供方法addremove(我仍在猜测后一个操作的含义>>。)。


请帮助我改进代码(样式、错误等)

我不想把这个作为我回答的要点,所以只是非常简短地从我的脑海中浮现出来,一些问题:

  • 您应该#include <iostream>代替#include <iostream.h>,然后添加 ausing namespace std;或写(例如)std::cout代替cout.

  • 尝试摆脱friend. 您应该能够以不需要的方式设计您的课程。friend很容易被滥用来绕过适当的封装。但是封装是您在 OOP 中绝对应该考虑的事情。

  • 虽然这不是给 C++ 初学者的建议,但如果您将链表类变成模板类,它可以存储与ints 不同的值。只需将此作为未来改进的提示。


最后:

  • 只需使用C++ 标准库中包含的 STL(“标准模板库”)容器。我知道“自己动手”有助于理解这些数据结构的工作原理,但请注意,C++ 标准库已经包含一组可靠且高效的数据容器。
于 2010-06-13T11:22:40.883 回答
1
  1. 0 应该为 NULL

  2. 仅在您不关心您的代码是否公开的情况下才内联,通常实现放在单独的文件 Mylist.cpp 文件中。

  3. 为什么你的析构函数是虚拟的,你有继承吗?

  4. 您可以只定义结构节点而不是单独的类,它可以更好地定义您的练习列表,例如在 stl 中。http://www.sgi.com/tech/stl/List.html http://www.cplusplus.com/reference/stl/list/

在 C++ 中常见的使用 Java 中的向量与链表 http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html

于 2010-06-13T18:06:26.237 回答