码迷,mamicode.com
首页 > 编程语言 > 详细

算法之美_源代码发布(5)

时间:2016-01-28 21:16:44      阅读:393      评论:0      收藏:0      [点我收藏+]

标签:

本文辑录了《算法之美——隐匿在数据结构背后的语言》(电子工业出版社2016年出版)一书第5~6章之代码(P149~P183)。全文目录、“45个算法”目录“22个经典问题目录”,以及有奖捉虫活动详情请见如下链接:http://blog.csdn.net/baimafujinji/article/details/50484348

附录中的经典笔试、面试问题参考答案请见:

http://blog.csdn.net/baimafujinji/article/details/50484683

技术分享


In general, 我不太喜欢翻开一本书(技术书),里面密密麻麻的全部都是代码。所以我也希望能够在我的书中留下更多空间去讨论原理。当然,代码也很重要,所有的一切原理最终都要落实到代码上。为此我习惯于在博客中上传代码,而非是把他们全部罗列到书中去挤占篇幅。

如果你是该书的读者,强烈建议你加入算法学习群(495573865),内有更多资源等你,而你在读书中遇到的疑问也将得到我第一时间的解答。更多关注本博客,我将陆续发布该书全部源代码至本博客。


P149:优先级队列的实现


template <class T>
class PriQueueNode{
public:
	T data;
	PriQueueNode<T>* link;
	PriQueueNode(T& value):data(value),link(NULL){}
};

template <class T>
class PriQueue{

	PriQueueNode<T>* front;
	PriQueueNode<T>* back;

public:
	PriQueue():front(NULL),back(NULL){}
	void EnQueue(T& element);
	T DelQueue();
	T& GetFront();
	void MakeEmpty();
	bool IsEmpty();
};

template <class T>
void PriQueue<T>::EnQueue(T& value)
{
	PriQueueNode<T>* add = new PriQueueNode<T>(value);
	if(front == NULL)
		front = back = add;
	else
	{
		back->link = add;
		back = back->link;
	}
}

template <class T>
T PriQueue<T>::DelQueue()
{
	PriQueueNode<T>* seek = front->link;		//遍历队列,寻找最小元素的指针
	PriQueueNode<T>* min = front;       			//指向最小元素的指针
	T minData;                        				//记录最小元素的数据
	while(seek!=NULL){
		if(seek->data < min->data)       		//寻找最小元素
			min = seek;
		seek = seek->link;
	}

	seek = front;                       			//指针重回队列头部
	while(seek!=NULL&&seek->link!=min)			//寻找最小元素的前驱结点
	{
		seek = seek->link;
	}

	if(seek == NULL){							//如果最小元素位于队列头部
		minData = front->data;
		front = front->link;					//更新队头指针
		delete min;
	}

	if(min->link == NULL)						//如果最小元素位于队列尾部
		back = seek;							//更新队尾指针

	if(seek!=NULL){								//如果最小元素位于队列中间,无需更新
		minData = min->data;					//队头指针与队尾指针,直接删除即可
		seek->link = min->link;
		delete min;
	}
	return  minData;							//返回数据
} 

template<class T>
T& PriQueue<T>::GetFront(){
	assert(!this->IsEmpty());
		return front->data;
}

template<class T>
void PriQueue<T>::MakeEmpty(){
	while(!IsEmpty()){
		this->DelQueue();
	}
}

template<class T>
bool PriQueue<T>::IsEmpty()
{
	return front == NULL;
}

P151:STL中的Stack应用示例1


#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <stack>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	stack<int> myStack;

	//入栈与出栈
	myStack.push(5);
	myStack.push(6);
	myStack.push(7);
	myStack.pop();

	cout << myStack.top() << endl;
	cout << myStack.size() << endl;
	cout << myStack.empty() << endl;


	system("PAUSE");
	return 0;
}



P152:STL中的Stack应用示例2


#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <stack>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

	ifstream inf;
	inf.open("temp.txt");

	if ( !inf ) {
		cerr << "cannot open file for input!" << endl;
		return EXIT_FAILURE;
	}

	stack<string> s;
	string line;

	while (getline(inf, line)) {
		s.push(line);
	}

	inf.close();

	while (!s.empty()) {
		cout << s.top() << endl;
		s.pop();
	}

	system("PAUSE");
	return 0;
}

P153: STL中的queue使用示例


#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <queue>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

	queue<int> myQueue;

	//添加元素与删除元素
	myQueue.push(5);
	myQueue.push(6);
	myQueue.push(7);

	myQueue.pop();

	cout << myQueue.front() << endl;
	cout << myQueue.back() << endl;

	cout << myQueue.size() << endl;
	cout << myQueue.empty() << endl;

	system("PAUSE");
	return 0;
}

P154:基于FIFO策略的内存页面淘汰过程模拟


#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <queue>

using namespace std;

bool existOrNot(int num, queue<int> myQueue)
{
	while(!myQueue.empty())
	{
		if(myQueue.front()==num)
			return true;
		else myQueue.pop();
	}
	return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
	queue<int> memQueue;

	int page[] ={4, 3, 2, 1, 4, 3, 5, 4, 3, 2, 1, 5};
	int times = 12;
	int tmpValue;

	for(int i = 0; i < 12; i++)
	{
		if(memQueue.size()<3)
			memQueue.push(page[i]);
		else 
		{
						
			if(existOrNot(page[i], memQueue))
			{
				times--;
			}
			else
			{
				memQueue.pop();
				memQueue.push(page[i]);
			}
		}

		int size = memQueue.size();
		while(size>0)
		{
			cout<<memQueue.front()<<" ";
			tmpValue = memQueue.front();
			memQueue.pop();
			memQueue.push(tmpValue);
			size--;
		}

		cout<<endl;
	}
	
	cout<<"使用FIFO策略时,共发生缺页中断"<<times<<"次."<<endl;

	system("PAUSE");
	return 0;
}


P156:STL中的priority_queue使用示例1


#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <queue>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

	priority_queue<int> Q;
	Q.push(1);
	Q.push(5);
	Q.push(2);
	Q.push(4);
	Q.push(6);
	Q.push(3);
	
	int size = Q.size();

	for(int i = 0; i< size; i++)
	{
		cout<<Q.top()<<endl;
		Q.pop();
	}

	cout<< endl << Q.empty() <<endl;


	system("PAUSE");
	return 0;
}


P157:STL中的priority_queue使用示例2


#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <queue>

using namespace std;

class myCompare{
public:
    bool operator () (const int& a,const int& b)
    {
        return a > b;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
	priority_queue<int, vector<int>, myCompare> Q;
	Q.push(1);
	Q.push(5);
	Q.push(2);
	Q.push(4);
	Q.push(6);
	Q.push(3);
	
	int size = Q.size();

	for(int i = 0; i < size; i++)
	{
		cout<<Q.top()<<endl;
		Q.pop();
	}

	cout<< endl << Q.empty() <<endl;

	system("PAUSE");
	return 0;
}


P161:阶乘的递归求解函数


int factorial(int n) {
	if (n == 0) {
		return 1;
	} 
	else {
		int value = factorial(n - 1);
		return n * value;
	}
}


P163:递归实现的二分查找


#include "stdio.h"
#include <vector>
#include <iostream>

using namespace std;

int binarySearch(const vector<int> & a, const int & x, int low, int high)
{
	if(low>high)
		return -1;

	int mid = (low + high)/2;
	//二分查找法的递归核心部分
	if(a[mid]<x)
		return binarySearch(a, x, mid+1, high);
	else if(x<a[mid])
		return binarySearch(a, x, low, mid-1);
	else
		return mid;
}

int Search(const vector<int> & a, const int & x)
{
	return binarySearch(a, x, 0, a.size()-1);
}

void main()
{
	vector<int> box;

	box.push_back(1);
	box.push_back(4);
	box.push_back(6);
	box.push_back(7);
	box.push_back(8);
	box.push_back(10);
	box.push_back(13);
	box.push_back(21);
	box.push_back(22);
	box.push_back(30);

	const int searchValue = 22;

	int result = Search(box, searchValue);

	if(result == -1)
		cout<<"要查的数字不在数组内!"<<endl;
	else
		cout<<searchValue<<"的位置在第"<<++result<<"位"<<endl;
}


P164:斐波那契数列的递归实现


int Fib(int n){
	if(n<=1) return n;
	else return Fib(n-1)+Fib(n-2);
}


P165:递归的顺序示例程序


#include "stdio.h"

void recursiveFunction1 ( int num ) 
{ 
	if ( num < 5 ) 
	{ 
		printf ( "%d \n" , num ) ; 
		recursiveFunction1 ( num +1 ) ; 
	} 
}

void recursiveFunction2 ( int num ) 
{ 
	if ( num < 5 ) 
	{ 
		recursiveFunction2 ( num +1 ) ; 
		printf ( "%d \n" , num ) ; 
	}
}

void main()
{
	recursiveFunction1(0);
	recursiveFunction2(0);
}

P168-1:求和函数的递归实现


int Sum( int n )
{
	if ( n==1 )
		return 1;
	else
		return Sum(n-1)+n;
}


P168-2:斐波那契数列的迭代实现


int Fib ( int n ) { 
	if ( n <= 1 ) return n; 
	int twoback = 0;
	int oneback = 1;
	int Current;
	for ( int i = 2; i <= n; i++ ) { 
		Current = twoback + oneback;
		twoback = oneback;
		oneback = Current; 
	 } 
	return Current; 
} 

P169:阶乘函数的尾递归实现


int factorial(int acc , int x) 
{
	if (x <= 1)
		return acc;
	else 
		return factorial ( x * acc, x - 1 );
}


P170-1:求解最大公约数的欧几里德算法(尾递归实现)


int gcd(int a, int b)
{
	if (b == 0)
		return a;
	else
		return gcd(b, a%b);
}


P170-2:求解最大公约数的欧几里德算法(非递归实现)


int gcd ( int a, int b ) 
{ 
	while ( b != 0 )
	{ 
		int r = a % b; 
		a = b; 
		b = r; 
	} return a;
}


P173: 汉诺塔问题


#include "stdafx.h"
#include <fstream>
#include <iostream>

using namespace std;

//盘子的数目
#define numOfDisks 10

//在文本文件out.txt中输出结果
ofstream fout("out.txt");

void Move(int n,char x,char y)
{
	fout<<"move "<<n<<" from "<<x<<" to "<<y<<endl;
}

//递归求解
void Hannoi(int n,char a,char b,char c)
{
	if(n==1)
		Move(1,a,c);
	else
	{
		Hannoi(n-1,a,c,b);
		Move(n,a,c);
		Hannoi(n-1,b,a,c);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	fout<<"The solution for Hanoi, when the number of disks is "<<
		numOfDisks<<endl;
	Hannoi(numOfDisks,‘a‘,‘b‘,‘c‘);
	fout.close();
	cout<<"The End! Please Check out.txt."<<endl;

	system("pause"); 
	return 0;
}

P175:传染病问题


main.cpp文件


#include <iostream>
#include <string>
#include <cstdlib>

#include "grid.h"

using namespace std;

#define ROWS 6
#define COLS 6
#define TOTAL 13 // 被感染点的总数

// 标记被感染点的坐标的数组
int theCity[TOTAL][2] = {
	{0,0},
	{1,1},
	{2,2},
	{2,3},
	{2,5},
	{3,2},
	{3,3},
	{3,5},
	{4,0},
	{4,2},
	{4,3},
	{4,5},
	{5,0}
};

int main () {

  grid *g;
  int col;
  int row;

  g = new grid ((int*)theCity, ROWS, COLS, TOTAL);

  cout << "请输入要检测点的坐标 格式: x,y" << endl;
  scanf("%d,%d", &row, &col);

  cout << "The colony including the cell at " 
       << "(" << row << "," << col << ")"
       << " has an area of " << g->count (row,col) << " units." << endl;

  cout << *g << endl;

  delete g;
  
  return EXIT_SUCCESS;
}

grid.h文件


#ifndef GRID_H
#define GRID_H

#include <string>
#include <vector>

using namespace std;

const bool INFECTED = true;
const bool NOT_INFECTED = false;

class grid;

class grid {

    int rows;
    int cols;
	int number;
    vector<bool> *area;
	vector<bool> *marked_area;

    int indexof (int row, int col) const;
    bool infected(int row, int col) const;
	void caculate(int row,int col);

  public:
    grid (int* theCity, int, int, int);
    ~grid ();

    int count (int row, int col);

    friend ostream &operator<<(ostream &stream, const grid& ob);

};

#endif

grid.cpp文件


#include <iostream>
#include <fstream>

using namespace std;

#include "grid.h"

int grid::indexof (int row, int col) const {
  return row*cols+col;
}

bool grid::infected(int row, int col) const {
  return (area->operator[](indexof(row, col)) == INFECTED);
}

//构造函数
grid::grid (int* theCity, int row, int col, int total) {

  number=0;

  rows = row;
  cols = col;

  area = new vector<bool>(rows*cols, NOT_INFECTED);
  marked_area = new vector<bool>(rows*cols, NOT_INFECTED);

  for (int i=0; i<total; i++) { 
  
    int blob_row;
    int blob_col;

	blob_row = theCity[i*2];
	blob_col = theCity[i*2+1];

    area->operator[](indexof(blob_row,blob_col)) = INFECTED;
  }
}

//析构函数
grid::~grid () {
  delete area;
  delete marked_area;
}

//在被感染的细胞处添加一个(+),运算符重载
ostream &operator<<(ostream &stream, const grid& ob) {

  for (int row=0; row < ob.rows; row++) { 
    
    for (int col=0; col < ob.cols; col++) {
      stream << ob.area->operator[](ob.indexof(row, col));
	  if(ob.marked_area->operator[](ob.indexof(row, col)))
		  stream << "+  ";
	  else
		  stream << "   ";
    }

    stream << endl;
  }

  stream << endl;
  return stream;
}

int grid::count (int row, int col) 
{
	caculate(row,col);
    return number;
}

//递归核心部分,进行八个方向的检查
void grid::caculate(int row,int col)
{
	if (row<0||col<0||row>=rows||col>=cols||marked_area->operator [](indexof(row,col)))
		return;
	if (infected(row,col))
	{
		marked_area->operator[](indexof(row, col)) = INFECTED;
		number++;
		caculate(row,col+1);
		caculate(row,col-1);
		caculate(row+1,col);
		caculate(row-1,col);
		caculate(row+1,col+1);
		caculate(row-1,col-1);
		caculate(row+1,col-1);
		caculate(row-1,col+1);
	}
}

sample.grid 文件内容


6 6

0 0
1 1
2 2
2 3
2 5
3 2
3 3
3 5
4 0
4 2
4 3
4 5
5 0


P177:迷宫问题


#include <vector>
#include <iostream>
using namespace std;

// 把迷宫表示为n个有编码路口的集合
// 定义路口类
class Crossing
{
public:
	// 0为不通 路口的三个方向
	int turn1;
	int turn2;
	int turn3;

public:
	Crossing(int turn1, int turn2, int turn3)
	{
		Crossing::turn1 = turn1;
		Crossing::turn2 = turn2;
		Crossing::turn3 = turn3;
	}	
};

// 定义迷宫类
class Maze
{
private:
	int exit; //出口编码
	vector<Crossing> crossings; //路口集合
	vector<int> result;

public:
	Maze(int the_exit, vector<Crossing> the_crossings)
	{
		exit = the_exit;
		crossings = the_crossings;
	}
	findExit(int entrance); //迷宫求解
	getResult(); //取得迷宫解并打印
	
};

//迷宫求解核心算法
Maze::findExit(int entrance)
{
	if(entrance > 0)
	{
		if(entrance == Maze::exit)
		{
			result.push_back(entrance);
			return 1;
		}
		if(findExit(crossings[entrance].turn1))
		{
			result.push_back(entrance);
			return 1;
		}
		if(findExit(crossings[entrance].turn2))
		{
			result.push_back(entrance);
			return 1;
		}
		if(findExit(crossings[entrance].turn3))
		{
			result.push_back(entrance);
			return 1;
		}
	}

	return 0;
}

Maze::getResult()
{
	findExit(1);
	
	for(int i = result.size(); i>0; i--)
		cout << result[i-1] << "->";
	cout << "Exit" << endl;
}

void main()
{
	// 创建一个迷宫 9个路口 出口为10
	Crossing c1(2,0,0);
	Crossing c2(4,0,0);
	Crossing c3(0,0,0);
	Crossing c4(3,5,0);
	Crossing c5(6,0,0);
	Crossing c6(7,0,0);
	Crossing c7(8,9,0);
	Crossing c8(0,0,0);
	Crossing c9(10,0,0);
	Crossing c0(0,0,0);

	vector<Crossing> crossings;
	crossings.push_back(c0);
	crossings.push_back(c1);
	crossings.push_back(c2);
	crossings.push_back(c3);
	crossings.push_back(c4);
	crossings.push_back(c5);
	crossings.push_back(c6);
	crossings.push_back(c7);
	crossings.push_back(c8);
	crossings.push_back(c9);

	Maze newMaze(10, crossings);
	newMaze.getResult();

	return;
}


P182:八皇后问题

请参见博文

数据结构与算法中的“递归”——用回溯法求解8皇后问题

(http://blog.csdn.net/baimafujinji/article/details/6510621)




内容简介:探秘算法世界,求索数据结构之道;汇集经典问题,畅享编程技法之趣;点拨求职热点,敲开业界名企之门。本书围绕算法与数据结构这个话题,循序渐进、深入浅出地介绍了现代计算机技术中常用的四十余个经典算法,以及回溯法、分治法、贪婪法和动态规划等算法设计思想。在此过程中,本书也系统地讲解了链表(包括单向链表、单向循环链表和双向循环链表)、栈、队列(包括普通队列和优先级队列)、树(包括二叉树、哈夫曼树、堆、红黑树、AVL树和字典树)、图、集合(包括不相交集)与字典等常用数据结构。同时,通过对二十二个经典问题(包括约瑟夫环问题、汉诺塔问题、八皇后问题和骑士周游问题等)的讲解,逐步揭开隐匿在数据结构背后的算法原理,力图帮助读者夯实知识储备,激活思维技巧,并最终冲破阻碍编程能力提升的重重藩篱。辅有完整的C++源代码,并穿插介绍了STL中的各种容器。


网上书店:

China-pub中国互动出版网:http://product.china-pub.com/4911922

当当网:http://product.dangdang.com/23851244.html

亚马逊:http://www.amazon.cn/%E7%AE%97%E6%B3%95%E4%B9%8B%E7%BE%8E-%E9%9A%90%E5%8C%BF%E5%9C%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E8%83%8C%E5%90%8E%E7%9A%84%E5%8E%9F%E7%90%86-%E5%B7%A6%E9%A3%9E/dp/B01AGNUIE8/ref=sr_1_8?ie=UTF8&qid=1453527399&sr=8-8&keywords=%E5%B7%A6%E9%A3%9E


算法之美_源代码发布(5)

标签:

原文地址:http://blog.csdn.net/baimafujinji/article/details/50602547

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!