【练习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 << " /*end*/ " << 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 << " /*end*/ " << endl; 37 38 //测试printlots,打印word的第2,3,5,7个元素 39 cout << "/*printlots()*/" << endl; 40 word.printlots(number); 41 cout << " /*end*/ " << endl; 42 43 system("pause"); 44 }
在对此前的链表例程
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 }