【Weiss】【第03章】练习3.2

【练习3.2】

给你一个链表L和另一个链表P,它们包含以升序排列的整数。操作printlots(L,P)将打印L中那些由P所指定的位置上的元素。

例如,如果p=1,3,4,6,那么,L的第一、第三、第四和第六个元素被打印出来。

你应该只使用基本的表操作,该过程的运行时间是多少?

 

Answer:

老样子,先放折叠的实测代码。

 1 #include <iostream>
 2 #include <string>
 3 #include "linklist.h"
 4 using namespace std;
 5 using namespace linklist;
 6 template class List<unsigned int>;
 7 template class List<string>;
 8 int main(void)
 9 {
10     List<unsigned int> number;
11 
12     //测试按升序插入
13     cout << "/*addinorder()*/" << endl;
14     number.addinorder(11);
15     number.addinorder(13);
16     number.addinorder(7);
17     number.addinorder(17);
18     number.addinorder(3);
19     number.addinorder(2);
20     number.addinorder(5);
21     number.traverse();
22     cout << "\n/*end*/\n\n" << endl;
23 
24     List<string> word;
25     cout << "/*initialize*/" << endl;
26     word.additem("The");
27     word.additem("day");
28     word.additem("after");
29     word.additem("tommorow");
30     word.additem("will");
31     word.additem("be");
32     word.additem("a");
33     word.additem("sunny");
34     word.additem("day");
35     word.traverse();
36     cout << "\n/*end*/\n\n" << endl;
37 
38     //测试printlots,打印word的第2,3,5,7个元素
39     cout << "/*printlots()*/" << endl;
40     word.printlots(number);
41     cout << "\n/*end*/\n\n" << endl;
42     
43     system("pause");
44 }
View Code

在对此前的链表例程

http://www.cnblogs.com/catnip/p/4328889.html

添加下面的成员函数后(类内成员函数声明需自行添加),该实测代码可以正确运行。

 

因为条件的链表是升序的,所以虽然没要求写,这儿首先还是在链表例程里面加了个自动按升序插入的例程。

 1 //练习3.2新增,按序插入
 2 template <typename T> bool List<T>::addinorder(const T &item)
 3 {
 4     Node<T>* pnew = new Node<T>(item);
 5     Node<T>* curr = front;
 6     Node<T>* prev = nullptr;
 7     while (curr != nullptr && curr->data < item)
 8     {
 9         prev = curr;
10         curr = curr->next;
11     }
12     //如果元素小于头元素,则头指针指向新节点
13     if (prev == nullptr)
14         front = pnew;
15     //否则,找到最后一个不大于元素的节点,将节点插入在此后
16     else
17         prev->next = pnew;
18     //最后,新节点的后向指针连接第一个比新元素大(或为空)的节点
19     pnew->next = curr;
20     ++length;
21     return true;
22 }

然后,虽然题目中要求两个链表元素都是整数,实际上只要第二个链表元素是整数就可以。

假如第一个链表的元素不是整数,那么类模板的一个实例就要访问另一个实例,则需加上一句友元声明。

1 //头节点及链表主体操作
2 template <typename T> class List
3 {
4     template <typename X> friend class List;
5         //......
6 }

最后,按题目要求打印的例程

 1 //练习3.2新增,坑爹的函数....
 2 template <typename T> void List<T>::printlots(const List<unsigned int>& inorder)
 3 {
 4     //计数器,记录已经查询到当原链表第几个元素
 5     //不同于数组,计数器从“第一个”开始计算
 6     unsigned int counter = 1;
 7     Node<T>* scan = front;
 8     for (Node<unsigned int>* iter = inorder.front; iter != nullptr; iter = iter->next)
 9     {
10         //遍历辅助链表,iter->data表示“需要原链表输出其第iter->data个元素”
11         //当data过大时直接返回
12         if (iter->data > length)
13             return;
14         //迭代直至counter==index并打印
15         for (; counter < iter->data; ++counter)
16             scan = scan->next;
17         cout << scan->data << ends;
18     }
19 }

 

posted @ 2015-03-11 05:59  猫薄荷喂狗  阅读(365)  评论(0编辑  收藏  举报