C++程序设计第二章作业讲评
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
template <class ElemType> void SqList1<ElemType>::Reverse() { ElemType temp; //临时存储 int l = len/2; for (int i = 0; i < l; i++) { temp = elem[i]; elem[i] = elem[len-i-1]; elem[len-i-1] = temp; } 边界测试:
P47 第6题
• 题目解读
– 条件:有序单链表 – 要求:提高算法的时间性能到O(m+n)
• 问题:原算法的效率问题在哪里?
template<class T> void mergelist(LinkList<T> &La, LinkList<T>&Lb, LinkList<T> &Lc) { int k, i, j, La_len, Lb_len; 每个结点访问1次的时间 T ai, bj; 复杂度是O(n),n个结点都 k=1;i=j=1; 全部结点插入O(m+n) 有可能被访问,为O(n*n) La_len=La.Length(); Lb_len=Lb.Length(); while ( i<=La_len && j<=Lb_len ) //出现重复处理语句 优化1: Lc.Append(ai ); { La.GetElem(ai, i); Lb.GetElem(bj, j); if (ai<bj) template<class ElemType> { Lc.Insert(ai,k ); i++; } bool LinkList<ElemType>::GetElem(ElemType &e, int i) else const { { Lc.Insert(bj,k ); j++; } if (i < 1 || i > len) return false; k++; LinkNode<ElemType> *p = head->next; int k = 1; } while (k < i) { //O(n) while (i<= La_len) k++; {La.GetElem(ai, i); Lc.Insert(ai,k p );= p->next; } k++; i++; } e = p->data; while (j<=Lb_len) return {Lb.GetElem(bj, j); Lc.Insert(bj, k); true; } k++; j++; } }
第二章作业讲评
P47:第1题
• 题目关键词解读——锻炼理解能力
– “就类模板写一成员函数”
• 就类模板——基于类模板 • 增加一个成员函数
– “就地逆置线性表中的数据”
• 就地——使用原来的存储空间,结果就保存在原来 的存储空间中 • 逆置——逻辑顺序反向
template <class ElemType> class SqList1:public List<ElemType> •在什么位置添加逆置函数的声明? { public: •在基类?在顺序表类? SqList1(int m = 0); •考虑到基类模板的通用性,不作改动。 SqList1(const SqList1<ElemType>&); •仅在派生类中增加逆置功能。 ~SqList1(); bool IsEmpty()const {return len <= 0;} int Length()const {return len;} void Clear(){len=0;} bool GetElem(ElemType&, int) const; bool SetElem(const ElemType&, int); int LocateElem(const ElemType&) const; int LocatePrior(const ElemType&) const; int LocateNext(const ElemType&) const; bool Insert(const ElemType&, int ); bool Append(const ElemType&); bool Delete(ElemType&, int); void Traverse() const; SqList1<ElemType> operator=(const SqList1<ElemType>&); void Reverse(); private: int len; void CopyFrom(const SqList1<ElemType>&); int size; ElemType *elem; };
优化GetElem(ElemType &e, int i)
template<class ElemType> bool LinkList<ElemType>:: GetElem(ElemType &e, int i) const { if (i < 1 || i > len) return false; LinkNode<ElemType> *p; int k = 1; p = head->next; while (k < i) { p = p->next; •每次查找从头开始 k++; •用变量pos记录当前 } 查找序号; e = p->data; •用指针current记录当 return true; 前查找位置; } •缩短查找长度 template<class ElemType> bool LinkList<ElemType>:: GetElem(ElemType &e, int i) const { int k ; LinkNode<ElemType> *p; if (i < 1 || i > len) return false; if (i == pos) { //如果是当前位置 e = current->data; return true; } if (pos == 0 || i < pos) { //如果在当前位置前面,从头开始 p = head->next; k = 1; } else { //如果在当前位置后从pos开始 p = current; k = pos; } while (k < i) { p = p->next; k++; } e = p->data; current = p; pos = i; return true; }
while (p) { //在原链中提取一个结点q q = p; p = p->next; //q 指向的结点插入到新链作为第一个结点 q->next = head->next; head->next = q; if (tail == head) //特别处理第一个结点 { tail = q; } } }
• 思路:
– 用原存储空间 – 调整链接关系 h
p q
p = head->next; head->next = NULL; tail = head;
p
q
p ∧
– 把头结点游离出来,用于新链的头结点。
t
h
∧百度文库
q
∧
q = p; p = p->next; q->next = head->next; head->next = q;
t
q
– 从原链提取一个结点,插入 到新链前面。
template <class ElemType> void LinkList<ElemType>::Reverse() { LinkNode<ElemType> *p = head->next; //原链第一个结点指针 LinkNode<ElemType> *q; //原链结点删除过程临时指针 //处理头结点,使其指向空链 head->next = NULL; tail = head;
}
增加一个1/2长度变 量,以提高效率
i=0与i=len-1调换; i=1与i=len-2
template <class ElemType> class LinkList: public List<ElemType> { •在派生类中增加逆置功能。 public: LinkList(); LinkList(const LinkList<ElemType>&); ~LinkList(); bool IsEmpty()const {return len <= 0;} int Length()const {return len;} void Clear(); bool GetElem (ElemType&,int) const; bool SetElem( const ElemType&,int); int LocateElem(const ElemType&) const; int LocatePrior(const ElemType&) const; int LocateNext(const ElemType&) const ; bool Insert(const ElemType&, int); bool Append(const ElemType&); bool Delete(ElemType&,int); void Traverse() const; LinkList<ElemType> operator=(const LinkList<ElemType>&); void Reverse(); private: int len; void CopyFrom(const LinkList<ElemType>&); LinkNode<ElemType> *head; LinkNode<ElemType> *tail; };
template <class ElemType> class LinkList: public List<ElemType> // {释放单链表中的所有数据结点 public: template <class ElemType> LinkList(); void LinkList<ElemType>::Clear() // 拷贝构造函数。从现有的单链表拷贝构造出一个单链表 LinkList(const LinkList<ElemType>&); ~LinkList(); // 构造一个带表头结点的空单链表 { template<class ElemType> bool IsEmpty()const {return len <= 0;} LinkNode<ElemType> template<class ElemType> *p = head->next, *q; int Length()const {return len;} void Clear(); LinkList<ElemType>::LinkList(const LinkList<ElemType> &r) LinkList<ElemType>::LinkList() while (p) { bool GetElem const; bool SetElem( const ElemType&,int); { (ElemType&,int) q = p->next ; { int LocateElem(const ElemType&) const; delete p;0; CopyFrom(r);// 从 r所引用的链表中复制所有的结点(值) = 0; pos = int LocatePrior(const ElemType&) len const; p = q; pos ElemType&) = 0; head = new LinkNode<ElemType> ; int LocateNext(const const = ; tail } = NULL; bool Insert(constcurrent ElemType&, int); head->next = NULL; current = NULL; 还有哪些成员函数 tail = head; bool Append(const ElemType&); }可以进一步优化以 } head->next = NULL; bool Delete(ElemType&,int); 提高访问效率? len = 0; pos = 0; current = NULL; void Traverse() const; } LinkList<ElemType> operator=(const LinkList<ElemType>&); void Reverse(); private: int len; int pos; void CopyFrom(const LinkList<ElemType>&); LinkNode<ElemType> *head; LinkNode<ElemType> *tail; LinkNode<ElemType> *current; };