自己的理解,概述:一种基本的数据结构。它的每一个节点(node)含有两部分的信息(1.该节点所存的数据 2.下一节点的地址) 因为每个节点存有下一节点的地址,所以所有节点可以形成一个链式的结构,即链表。最后一个节点若储存某一结点的信息,会使链表成为一个环形链表(可以用于解决约瑟夫环问题),每个节点还可以加上一个指向前一个节点的指针,这样链表就成为了一个双向链表。(参考STL库的List模板)
用一个类来包装整个链表,用一个结构体来表示链表的节点(用模板写成泛型) node作为list的一个private成员,公有成员包括:构造/析构函数,addnode()用来添加节点,deleting(int no)来指定删除节点(重载一个无参的delete()用来删除整个链表,放在析构函数里),modifying(int no,T a)用来找到某个节点,并修改其中的值,int getlength()const 获得链表的长度
定义一个节点:
template<typename T> class My_Node{ public: My_Node *pnext; My_Node *pprev; T data; };定义链表:
template<typename T> class My_List{ public: My_List(); ~My_List(){ DeleteNode(); std::cout<<"destruction complete"<<std::endl; } void AddNode(T inpdata); void DeleteNode(int no); void DeleteNode();//overload for destruction void Traversing(); void Modifying(int no,T modi); void Reverse(); int GetLength() const{return length;} T GetElement(); private: My_Node<T> *head; int length; };构造函数还是写一下,把length置为0,头节点初始化
//constructor template<typename T> My_List<T>::My_List(){ length=0; head = NULL; };添加一个结点,注意判断一下链表是否还是空的
//addlistnode template<typename T> void My_List<T>::AddNode(T inpdata){ My_Node<T> *next,*prev; if(!head) { head=new My_Node<T>; head->data=inpdata; head->pnext=NULL; head->pprev=NULL; } else { next=head; while(next!=NULL) { prev=next; next=next->pnext; } next=new My_Node<T>; prev->pnext=next; next->pprev=prev; next->data=inpdata; next->pnext=NULL; } length++; }遍历打印链表,测试时可以用
//traversing template<typename T> void My_List<T>::Traversing() { My_Node<T> *trav_ptr; trav_ptr=head; while(trav_ptr!=NULL) { std::cout<<trav_ptr->data<<" "; trav_ptr=trav_ptr->pnext; } std::cout<<"\n"; }删除节点、链表
//deleting node(default) template<typename T> void My_List<T>::DeleteNode(int no) { My_Node<T> *trav_ptr1,*trav_ptr2,*trav_ptr3; trav_ptr1=trav_ptr2=trav_ptr3=head; int cnt=0; if(no>=length)std::cout<<"range exceeded!"<<std::endl; else { while(cnt<no-2) { trav_ptr1=trav_ptr1->pnext; cnt++; } trav_ptr2=trav_ptr1->pnext; trav_ptr3=trav_ptr2->pnext; delete trav_ptr2; trav_ptr1->pnext=trav_ptr3; } } //deleting node(overload) template<typename T> void My_List<T>::DeleteNode() { My_Node<T> *trav_ptr1=head; My_Node<T> *trav_ptr2=head; while(trav_ptr2!=NULL) { trav_ptr2=trav_ptr2->pnext; delete trav_ptr1; trav_ptr1=trav_ptr2; } } //modifying data template<typename T> void My_List<T>::Modifying(int no,T modi) { int cnt=0; My_Node<T> *trav_ptr=head; if(no>=length)std::cout<<"range exceeded!"<<std::endl; else { while(cnt<no-1) { trav_ptr=trav_ptr->pnext; cnt++; } trav_ptr->data=modi; } }反转链表,写得很水,较为繁琐,日后来更新
template<typename T> void My_List<T>::Reverse() { My_Node<T> *next,*current; current=next=head; current=current->pnext; next=current->pnext; head->pnext=NULL; while(next!=NULL) { current->pnext=head; current->pprev=next; head=current; current=next; next=next->pnext; } current->pnext=head; head=current; }结:思考不够深入,还有些地方可以优化,请等我之后的更新吧…(咕