数据结构第2章花了2个礼拜才搞定,工作忙,业余时间少了。
总结2个算法:随机漫步和骑士旅行(题目参见p62)
随机漫步:一只大蟑螂在m*n的格子上随机行走,经过多少次可以走遍整个格子
// algorithm random walk.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <time.h>
using namespace std;
//Current status of bug
struct status
{
int x, y;
int passed;
int iterated;
};
//Map information
struct maps
{
int iLength, iWideth;
int **p;
};
class randomwalk
{
public:
randomwalk(int iLen, int iWide, int max_iter);
~randomwalk();
int walk(int i);
void algorithm();
void printWalk();
private:
struct status m_stStatus;
struct maps m_stMap;
int m_iMaxIter;
};
//Init map and status
randomwalk::randomwalk(int iLen, int iWide, int max_iter)
{
m_stMap.iLength = iLen;
m_stMap.iWideth = iWide;
m_stMap.p = new int *[iLen];
int i, j;
for(i = 0; i < iLen; ++i)
{
m_stMap.p[i] = new int[iWide];
}
for(i = 0 ; i < iLen; ++i)
for(j = 0; j < iWide; ++j)
m_stMap.p[i][j] = 0;
//random the position of bug, passed grid is 0
m_stStatus.passed = 0;
m_stStatus.iterated = 0;
m_stStatus.x = rand()%(iLen - 1);
m_stStatus.y = rand()%(iWide - 1);
m_iMaxIter = max_iter;
}
randomwalk::~randomwalk()
{
for(int i = 0; i < m_stMap.iLength; ++i)
delete []m_stMap.p[i];
delete []m_stMap.p;
}
//judge if walk is legal , if walk return 1, else return 0
int randomwalk::walk(int i)
{
switch(i)
{
case 0:
if(m_stStatus.x > 0 && m_stStatus.y < (m_stMap.iWideth - 1))
{
m_stStatus.x--;
m_stStatus.y++;
return 1;
}
return 0;
case 1:
if(m_stStatus.y < (m_stMap.iWideth - 1))
{
m_stStatus.y++;
return 1;
}
return 0;
case 2:
if(m_stStatus.x < (m_stMap.iLength - 1) && m_stStatus.y < (m_stMap.iWideth -1) )
{
m_stStatus.x++;
m_stStatus.y++;
return 1;
}
return 0;
case 3:
if(m_stStatus.x <(m_stMap.iLength - 1))
{
m_stStatus.x++;
return 1;
}
return 0;
case 4:
if(m_stStatus.x < (m_stMap.iLength - 1) && m_stStatus.y > 0)
{
m_stStatus.x++;
m_stStatus.y--;
return 1;
}
return 0;
case 5:
if(m_stStatus.y >0)
{
m_stStatus.y--;
return 1;
}
return 0;
case 6:
if(m_stStatus.x >0 && m_stStatus.y > 0)
{
m_stStatus.x--;
m_stStatus.y--;
return 1;
}
return 0;
case 7:
if(m_stStatus.x > 0)
{
m_stStatus.x--;
return 1;
}
return 0;
default:
printf("Error walk");
return 0;
}
}
//walk all grids
void randomwalk::algorithm()
{
while(m_stStatus.passed < (m_stMap.iLength*m_stMap.iWideth) && m_stStatus.iterated < m_iMaxIter)
{
int rnd = rand()%8;
if(walk(rnd))
{
int i = m_stStatus.x, j = m_stStatus.y;
if(m_stMap.p[i][j] == 0)
{
m_stStatus.passed++;
}
m_stMap.p[i][j]++;
m_stStatus.iterated++;
}
}
}
void randomwalk::printWalk()
{
printf("Walk times is %d.\n", m_stStatus.iterated);
for(int i = 0; i < m_stMap.iLength; ++i)
{
for(int j = 0; j< m_stMap.iWideth; ++j)
{
printf("%3d ", m_stMap.p[i][j]);
}
printf("\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
srand((int)time(0));
class randomwalk *pcRandWalk;
pcRandWalk = new randomwalk(15, 15, 50000);
pcRandWalk->algorithm();
pcRandWalk->printWalk();
delete pcRandWalk;
return 0;
}
骑士旅行:一个国际象棋棋盘,随机一个位置(i,j),在不重复的情况下走L步,走遍整个棋盘。
算法:board[8][8] = {0};当位于(i,j)时,下一步pos = movpos(i,j),if(pos = 0 ) 退出,打印;else 存储下一步的可能的坐标;
对可能的坐标 posnext = movpos(nextx,nexty); 找到最小的posnext,并把该坐标 = 当前坐标,mboard[i][j] = count++;
代码如下:也可以采用递归,我这个方法比较2,各位看官谅解。
// knight's tour.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
int ktmove1[8] = {-2,-1,1,2,2,1,-1,-2};
int ktmove2[8] = {1,2,2,1,-1,-2,-2,-1};
struct coordinate
{
int x, y;
};
struct nextpos
{
int nextx[8], nexty[8];
int pos;
};
class lshaped
{
public:
lshaped(int x, int y);
int movepos(int x, int y, struct nextpos *pnext);
int move();
void print();
private:
int m_board[8][8];
int m_count;
struct coordinate m_stCondition;
struct nextpos m_stNextPos;
bool m_flag;
};
//init board
lshaped::lshaped(int x, int y)
{
for(int i = 0; i < 8; ++i)
for(int j = 0; j < 8; ++j)
m_board[i][j] = 0;
m_stCondition.x = x;
m_stCondition.y = y;
m_count = 0;
m_flag = 1;
memset(&m_stNextPos, 0, sizeof(m_stNextPos));
}
//possible move position and return num
int lshaped::movepos(int x, int y, struct nextpos *pnext)
{
pnext->pos = 0;
for(int i = 0; i < 8; ++i)
{
if( (x + ktmove1[i]) < 8 && (x + ktmove1[i]) >= 0 &&
(y + ktmove2[i]) < 8 && (y + ktmove2[i]) >= 0 &&((x + ktmove1[i])!= 3 || (y + ktmove2[i])!=3) &&
m_board[x + ktmove1[i]][y + ktmove2[i]] == 0)
{
pnext->nextx[pnext->pos] = x + ktmove1[i];
pnext->nexty[pnext->pos] = y + ktmove2[i];
pnext->pos++;
}
}
return pnext->pos;
}
//begin to move, loop movepos, if pos = 0;printf else min = movepos(x[i],y[i]), postion + [min];
int lshaped::move()
{
int i;
int num, min = 8;
int index;
struct nextpos *ptemp = NULL;
i = movepos(m_stCondition.x, m_stCondition.y, &m_stNextPos);
if(i == 0)
{
return 1;
}
ptemp = (struct nextpos *)malloc(sizeof(struct nextpos));
memcpy(ptemp, &m_stNextPos, sizeof(struct nextpos));
for(int j = 0 ; j < i; ++j)
{
num = movepos( m_stNextPos.nextx[j],m_stNextPos.nexty[j], ptemp );
if(num < min)
{
min = num;
index = j;
}
}
free(ptemp);
m_stCondition.x = m_stNextPos.nextx[index];
m_stCondition.y = m_stNextPos.nexty[index];
m_board[m_stCondition.x][m_stCondition.y] = ++m_count;
return 0;
}
void lshaped::print()
{
for(int i = 0; i < 8; ++i)
{
for(int j = 0; j < 8; ++j)
{
printf("%2d ", m_board[i][j]);
}
printf("\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
class lshaped example(3, 3);
int flag = 1;
while(flag)
{
if(example.move())
flag = 0;
}
example.print();
return 0;
}