《数据结构与算法描述:c++实现》第3版第三章课后练习答案

《数据结构与算法描述: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 & operator<
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值