数据结构(华容道)实验报告实验名称:华容道学生姓名:班级:学号:日期:一、实验目的可以输入华容道游戏的起始布局,求出求解结果。
二、程序分析2.1存储结构链式存储结构2.2程序流程对于此类问题的求解,一般都是通过搜索空间的方法获得可行解法。
这里采用广度优先搜索。
理论上讲,广度优先算法得到的第一个解,一定是一个搜索步数最少的解(如有解存在),这正好是华容道游戏的需要。
广度优先搜索算法一般通过队列存储结构实现。
由当前布局状态判断哪些棋子可以移动,每移动一个棋子,得到一个新的布局状态,若不是最终解且该布局以前没有出现过,则入队。
显然算法在设计细节时需要考虑移动棋子的算法,以及如何判断新的布局状态是否出现过。
2.3关键算法分析算法1:MemoryPool::MemoryPool(unsigned int size){if (size <= 100)throw"size should be greater than 100.";m_Base = new char[size];if (!m_Base)throw"no enough memory.";m_PoolSize = size;m_Frist = NULL;InsertFreeBlock(m_Base, size - 2 * sizeof(BlockBorder));}void MemoryPool::InsertFreeBlock(void *p, int size){FreeBlockHead*s = (FreeBlockHead *)p;s->BlockLength = size;p = (char*)p + size + sizeof(BlockBorder);((BlockBorder*)p)->BlockLength = size;if (m_Frist)m_Frist->prior = s;s->next = m_Frist;s->prior = NULL;m_Frist = s;}void MemoryPool::DeleteFreeBlock(FreeBlockHead *p){if (!p->next && !p->prior){m_Frist = NULL;}else if (!p->next&&p->prior){p->prior->next = NULL;}else if (!p->prior){p->next->prior = NULL;m_Frist = p->next;}else{p->next->prior = p->prior;p->prior->next = p->next;}}void MemoryPool::SetUsedBorder(void *p, int size){((BlockBorder*)p)->BlockLength = -size;p = (char*)p + sizeof(BlockBorder) + size;((BlockBorder*)p)->BlockLength = -size;}void * MemoryPool::Allocate(int size){if (m_Frist == NULL) return NULL;FreeBlockHead *p = m_Frist;while (p&&p->MemorySize() < size)p = p->next;if (!p) return NULL;if (p->MemorySize() <= size + sizeof(FreeBlockHead) + sizeof(BlockBorder)) {DeleteFreeBlock(p);SetUsedBorder(p, p->BlockLength);return (char*)p + sizeof(BlockBorder);}else{int newsize = p->MemorySize() - size - 2 * sizeof(BlockBorder);DeleteFreeBlock(p);InsertFreeBlock(p, newsize);SetUsedBorder((char*)p + p->BlockSize(), size);return (char*)p + p->BlockSize() + sizeof(BlockBorder);}}BlockBorder * MemoryPool::GetCurrentBlock(void *p){return(BlockBorder*)((char*)p - sizeof(BlockBorder));}BlockBorder* MemoryPool::GetPreBlock(void *p){char *cp = (char*)GetCurrentBlock(p);if (cp == m_Base) return NULL;else{int len = *(int *)(cp - sizeof(BlockBorder));cp -= 2 * sizeof(BlockBorder) + (len < 0 ? -len : len);return (BlockBorder*)p;}}BlockBorder * MemoryPool::GetNextBlock(void *p){BlockBorder * bp = GetCurrentBlock(p);char *cp = (char*)bp + bp->BlockSize();return (cp == m_Base + m_PoolSize) ? NULL : (BlockBorder*)cp;}void MemoryPool::Free(void *p){BlockBorder * currentBlock = GetCurrentBlock(p);BlockBorder * nextBlock = GetNextBlock(p);if (nextBlock&&nextBlock->Free()){int size = nextBlock->BlockSize();DeleteFreeBlock((FreeBlockHead*)nextBlock);InsertFreeBlock(currentBlock, currentBlock->MemorySize() + size);}BlockBorder * preBlock = GetPreBlock(p);if (preBlock&&preBlock->Free()){DeleteFreeBlock((FreeBlockHead*)preBlock);InsertFreeBlock(preBlock, preBlock->MemorySize() + currentBlock->BlockSize());}else{InsertFreeBlock(currentBlock, currentBlock->MemorySize());}}MemoryPool::~MemoryPool(){cout << m_Frist << endl;cout <<"size:"<< m_Frist->MemorySize() << endl;if (m_Base)delete[]m_Base;}[1]算法功能(1)每个状态布局的结构定义struct G{char grid[5][4];//当前状态的布局char father[5][4];//到达当前状态的前一个状态布局};bool operator < (const G&a, const G&b){return memcmp(a.grid[0], b.grid[0], 20) < 0;}(2)棋子移动考虑到一些棋子一次可能有两种移动方式,设计MOVE函数返回移动方式的数目,参数NEWG指针指向为移动后的状态数组,每个元素为一种移动后的布局。
int Move(G&g, int i, int j, G* newg){if (g.grid[i][j] == '0')return 0;if ((g.grid[i][j] == 'C' || g.grid[i][j] == 'H') && i != 0 && g.grid[i - 1][j] == 'B'&&g.grid[i - 1][j + 1] == 'B'){GetNextG(&newg[0], &g, sizeof(G));int h = 1;if (g.grid[i][j] == 'C')h = 2;Slide(newg[0].grid, g.grid, i, j, -1, 0, h, 2);return 1;}if (g.grid[i][j] == 'C'&&i < 3 && g.grid[i + 2][j] == 'B'&&g.grid[i + 2][j + 1] == 'B' || g.grid[i][j] == 'H'&&i < 4 && g.grid[i + 1][j] == 'B'&&g.grid[i + 1][j + 1] == 'B') {GetNextG(&newg[0], &g, sizeof(G));int h = 1;if (g.grid[i][j] == 'C')h = 2;Slide(newg[0].grid, g.grid, i, j, 1, 0, h, 2);return 1;}if ((g.grid[i][j] == 'C' || g.grid[i][j] == 'G') && j != 0 && g.grid[i][j - 1] == 'B'&&g.grid[i + 1][j - 1] == 'B'){GetNextG(&newg[0], &g, sizeof(G));int w = 1;if (g.grid[i][j] == 'C')w = 2;Slide(newg[0].grid, g.grid, i, j, 0, -1, 2, w);return 1;}if (g.grid[i][j] == 'C'&&j< 2 && g.grid[i][j + 2] == 'B'&&g.grid[i + 1][j + 2] == 'B' || g.grid[i][j] == 'G'&&j< 3 && g.grid[i][j + 1] == 'B'&&g.grid[i + 1][j + 1] == 'B') {GetNextG(&newg[0], &g, sizeof(G));int w = 1;if (g.grid[i][j] == 'C')w = 2;Slide(newg[0].grid, g.grid, i, j, 0, 1, 2, w);return 1;}if (g.grid[i][j] == 'H'&&j != 0 && g.grid[i][j - 1] == 'B'){GetNextG(&newg[0], &g, sizeof(g));Slide(newg[0].grid, g.grid, i, j, 0, -1, 1, 2);int num = 1;if (j > 1 && g.grid[i][j - 2] == 'B'){GetNextG(&newg[1], &g, sizeof(G));Slide(newg[1].grid, g.grid, i, j, 0, -2, 1, 2);num++;}return num;}//。