《数据结构与算法描述:c++实现》第3版第三章课后练习答案
3.1 给定一个链表L和另一个链表P,包含以升序排列的整数。操作printLots(L,P)将打印L中那些由P指定的位置上的元素,例如,P = 1,3,4,6,那么L中的第1,3,4,6的元素被打印出来。使用公有的STL容器操作,运行时间为多少。
#include <stdio.h>
#include <stdlib.h>
#include <list>
#include <iterator>
#include <iostream>
#include<ctime>
using namespace std;
//3.1
template <typename Object>
void printLots(list<Object> L, list<int> P)
{
typename list<int>::const_iterator pIt;
typename list<Object>::const_iterator lIt;
for (pIt = P.begin(); pIt != P.end(); pIt++)
{
int num = *pIt;
int printNum = 0;
for (lIt = L.begin(); lIt != L.end(); lIt++)
{
printNum++;
if (printNum == num)
break;
}
cout << *lIt << " ";
}
cout << endl;
}
int main()
{
list<int> lst1;
list<int> lst2;
lst1.push_front(1); lst1.push_front(3); lst1.push_front(5); lst1.push_front(2);
lst1.push_front(7); lst1.push_front(9); lst1.push_front(25);lst1.push_front(11);
lst2.push_front(4); lst2.push_front(1); lst2.push_front(3); lst2.push_front(6);
lst1.sort();
lst2.sort();
cout << "List L:";
for (list<int>::iterator i = lst1.begin(); i != lst1.end(); i++)
cout << *i << " " ;
cout << endl;
cout << "List P:";
for (list<int>::iterator i = lst2.begin(); i != lst2.end(); i++)
cout << *i << " ";
cout << endl;
clock_t startTime, endTime;
startTime = clock();//计时开始
printLots(lst1, lst2);
endTime = clock();//计时结束
cout << "The run time is: " << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
system("pause");
return 0;
}
执行结果如下:
3.2 通过只调整链(而不是数据)来交换相邻的元素,使用a.单向链表,b.双向链表
void swapWithSingleNext(Node * beforep)
{
Node *p , *afterp;
p = before->next;
afterp = p->next; // both p and afterp assumed not NULL
p->next = afterp-> next;
beforep ->next = afterp;
afterp->next = p;
}
void swapWithDoubleNext(Node *p)
{
Node *beforep, *afterp;
beforep = p->prev;
afterp = p->next;
p->next = afterp->next;
beforep->next = afterp;
afterp->next = p;
p->next->prev = p;
p->prev = afterp;
afterp->prev = beforep;
}
3.3 实现STL的find例程,该例程返回的iterator包含从start开始一直到end(不包含end)的范围内第一个出现的x。如果x没有找到,就返回end。该非类全局函数的签名如下:
template<typename Iterator, typename Object>
iterator find(Iterator start, Iterator end, const Object & x)
template<typename Iterator, typename Object>
iterator find(Iterator start, Iterator end, const Object & x)
{
Iterator iter;
for (iter = start; iter!= end; iter++)
{
if (*iter == x || iter == end)
break;
}
return iter;
}
3.4 给定两个排序后的表L1和L2,写出一个程序仅使用基本的表操作来计算L1∩L2
template <typename Object>
list<Object> intersection(const list<Object> & L1,const list<Object> & L2)
{
list<Object> intersect;
typename list<Object>::const_iterator iterL1 = L1.begin();
typename list<Object>::const_iterator iterL2 = L2.begin();
while (iterL1 != L1.end() && iterL2 != L2.end())
{
if (*iterL1 == *iterL2)
{
//有相同的元素
intersect.push_back(*iterL1);
iterL1++;
iterL2++;
}
//L1的元素小,所以需要1的指针往后找
else if (*iterL1 < *iterL2)
iterL1++;
else
iterL2++;
}
return intersect;
}
3.5 给定两个排序后的表L1和L2,写出一个程序仅使用基本的表操作来计算L1∪L2
template <typename Object>
list<Object> intersection(const list<Object> & L1, const list<Object> & L2)
{
list<Object> intersect;
typename list<Object>::const_iterator iterL1 = L1.begin();
typename list<Object>::const_iterator iterL2 = L2.begin();
while (iterL1 != L1.end() && iterL2 != L2.end())
{
if (*iterL1 == *iterL2)
{
//有相同的元素
intersect.push_back(*iterL1);
iterL1++;
iterL2++;
}
//L1的元素小,所以需要1的指针往后找
else if (*iterL1 < *iterL2)
{
intersect.push_back(*iterL1);
iterL1++;
}
else
{
intersect.push_back(*iterL2);
iterL2++;
}
}
return intersect;
}
3.6 Josephus问题是下面这个游戏,有N个人坐成一圈,编号1到N,从编号为1的人开始传递热马铃薯。M次传递之后,持有热马铃薯的人退出游戏,圈缩小,然后游戏从退出人下面的人开始,继续进行,最终留下来的人获胜,这样,如果M=0并且N=5,那么参加游戏的人依次退出,5号获胜。如果M=1并且N=5,那么退出的顺序就行2,4,1,5
a.写一个程序解决Josephus问题,此时M和N为任意值,尽可能使程序高效,同时确保存储单元被正确处理。
b.程序运行的时间
c.M=1时,运行时间为多少?对于N的较大值,delete例程对程序运行速度的影响有多大
int main()
{
int m, n, numLeft, mPrime;
list<int> L;
list<int>::iterator iter;
cout << "Please enter the total num N and pass times M:" << endl;
cin >> n >> m;
numLeft = n;
mPrime = m % n;
for (int i = 1; i <= n; i++)
{
mPrime = mPrime % numLeft;
if (mPrime <= numLeft / 2)//out
{
for (int j = 0; j < mPrime; j++)
{
iter++;
if (iter == L.end())
iter = L.begin();
}
}
else // pass backward
{
for (int j = 0; j < mPrime; j++)
{
if (iter == L.begin())
iter = --L.end();
else
iter--;
}
}
cout << *iter << " ";
iter = L.erase(iter);
if (iter == L.end())
iter = L.begin();
}
cout << endl;
system("pause");
return 0;
}
3.7 修改Vector类,添加索引时的边界检测功能
Object &