动态内存分配与数据结构.ppt

重点掌握单链表数据结构的定义、类成员的定义及其相关操作! 在C/C++中允许结构(或对象)成员是结构自身的指针类型,通过指针引用自身这种类型的结构。但结构成员决不能是结构自身类型,即结构不能自己定义自己,这会导致一个无穷递归的定义ben。 只要改变链中结点指针的值,无需移动表中的元素,就能实现插入和删除操作。插入算法有三种情况,我们希望在单链表中包含数据infoi的结点之前插入一个新元素,则infoi可在第一个结点,或在中间结点,如未找到,则把新结点插在链尾结点之后。 链表操作次序非常重要, 要考虑清楚,否则会出现灾难性的后果 浪费一个头节点的空间 回想一下堆内存的相关知识 几点注意: 1. 模板类List 必须在模板类Node前面声明 2. NodeT *link; -- Node *link; 3. 声明为List的友元,既方便又安全 指出课本上不严谨的地方 在本例中没有给出Node类的复制构造函数,并非可以使用默认的复制构造函数,而是避开了所有使用它的情况,本例中函数的参数和返回值仅使用指向Node的指针,类定义中也没有用复制方式初始化。 单链表的复制构造函数和复制运算符是一个复杂的算法,与前文所编的复制构造函数和复制运算符构造相去甚远了。 顺序栈和链栈逻辑功能是一样,尽管这里两个栈模板的成员函数功能选择稍有出入,因为顺序栈可以随机访问其中的元素,而链栈只能顺序访问,但逻辑上完全可以做到一样(物理结构不同)。顺序栈必须先开一定大小内存空间,执行起来简单,速度快,可能溢出。链栈内存空间随用随开,不会溢出,但执行复杂(不断地动态分配),速度慢。 实际上已讲过! 回顾一下 1.IO操作符不能重载类的成员函数,一般声明为友元 student s; s.cout; // error, 与正常输入输出相反 couts;//ok, 所以operator()不能声明为student的成员函数 h 定义链表类: templatetypename Tclass List{ ... int count; public: List():count(0); ~List(); int Length(){return count;} //大大提高了效率 void InsertFront(NodeT* p){... count++;} void InsertRear(NodeT* p){... count++;} void InsertOrder(NodeT *p){... count++;} NodeT*DeleteNode(NodeT* p); }{... count--;} ... ... } 2.2 单链表类型模板 例5_h 单链表类型模板 链表类成员函数: templatetypename Tvoid ListT::PrintList(){//显示链表 NodeT* tempP=head-link; while(tempP!=0){ couttempP-info\t; tempP=tempP-link; } coutendl;} templatetypename Tvoid ListT::InsertFront(NodeT *p){ p-link=head-link; head-link=p; if(tail==head) tail=p;}//如果为空,修改tail指向 templatetypename Tvoid ListT::InsertRear(NodeT *p){ p-link=tail-link; //p-link=0; tail-link=p; tail=p;} 链表类成员函数: templatetypename T void ListT::InsertOrder(NodeT *p){ NodeT *tempP=head-link,*tempQ=head; //tempQ指向tempP前面的一个结点 while(tempP!=0){ if(p-infotempP-info)break; //找第一个比插入结点大的结点,由tempP指向 tempQ=tempP; tempP=tempP-link; } tempQ-InsertAfter(p); //插在tempP指向结点之前,tempQ之后 if(tail==tempQ) tail=tempQ-link;}//插入tail后面,修改tail templatetypena

文档评论(0)

1亿VIP精品文档

相关文档