Problem 1: Filling a Region
回溯思想填空白
#include <iostream>
#include "vector.h"
#include "grid.h"
using namespace std;
enum pixelStateT { White, Black };
struct pointT {
int row, col;
};
void FillReign(pointT pt, Grid<pixelStateT> & screen);
bool IsOffGrid(pointT pt, Grid<pixelStateT> & grid);
pointT move(pointT pt, int i);
int main() {
//创建图
Grid<pixelStateT> screen(10,10);
for(int i=0;i<10; i++) screen(0,i) = Black;
for(int i=0;i<10; i++) screen(1,i) = White;
for(int i=0;i<10; i++) screen(2,i) = Black;
for(int i=0;i<10; i++) screen(3,i) = White;
for(int i=0;i<10; i++) screen(4,i) = Black;
for(int i=0;i<10; i++) screen(5,i) = White;
for(int i=0;i<10; i++) screen(6,i) = Black;
for(int i=0;i<10; i++) screen(7,i) = White;
for(int i=0;i<10; i++) screen(8,i) = Black;
for(int i=0;i<10; i++) screen(9,i) = White;
//打印图
for(int i=0; i<10; i++){
cout<< screen(i,0)<<screen(i,1)<<screen(i,2)<<screen(i,3) <<screen(i,4)
<<screen(i,5)<<screen(i,6)<<screen(i,7)<<screen(i,8)<<screen(i,9)<<endl;
}
//选择点
cout <<"-------------"<<endl;
pointT pt;
pt.row = 7;
pt.col = 4;
//填充
FillReign(pt, screen);
//打印新图
for(int j=0; j<10; j++){
cout<< screen(j,0)<<screen(j,1)<<screen(j,2)<<screen(j,3) <<screen(j,4)
<<screen(j,5)<<screen(j,6)<<screen(j,7)<<screen(j,8)<<screen(j,9)<<endl;
}
return 0;
}
void FillReign(pointT pt, Grid<pixelStateT> & screen){
if (IsOffGrid(pt,screen))
return;
if (screen(pt.row, pt.col) == Black)
return;
screen(pt.row, pt.col) = Black;
for(int i=0; i<4; i++) {
FillReign(move(pt, i),screen);
}
}
bool IsOffGrid(pointT pt, Grid<pixelStateT> & grid){
return pt.row < 0 || pt.row >= grid.numRows() ||
pt.col < 0 || pt.col >= grid.numCols();
}
pointT move(pointT pt, int i){
pointT temp;
switch(i){
case 0: temp.row = pt.row-1; temp.col = pt.col ; break;
case 1: temp.row = pt.row+1; temp.col = pt.col ; break;
case 2: temp.row = pt.row; temp.col = pt.col-1 ; break;
case 3: temp.row = pt.row; temp.col = pt.col+1 ; break;
}
return temp;
/*
结果展示:
point (7,4):
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
-------------
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
1111111111
1111111111
0000000000
point (8,4):
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
-------------
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
1111111111
0000000000
*/
Problem 2: Shortest Path Through a Maze
由于mazesolve函数已经给出类,只需要稍微改改就行
int ShortestPathLength(pointT pt){
int shortest, len;
if(OutsideMaze(pt))
{
return 0;
}
if(IsMarked(pt))
{
return Nosolution;
}
shorest = NoSolution;
MarkSquire(pt);
for(directionT dir = North; dir <= West; dir = directionT(dir+1)){
if(!WallExists(pt,dir))
{
len = ShortestPathLength(AdjacentPoint(pt, dir));
if (len < shortest){
shortest = len;
}
}
}
UnmarkSquare(pt);
if (shortest == NoSolution){
return NoSolution;
}
else
{
return (shortest + 1);
}
}
Problem 3: Pointers
这个指针概念问题没什么说得
Problem 4: Linked List Warmup
a) 两种方法将vector改成链表,递归方法看看就好
Cell * ConvertToListIter(Vector<int> vector){
Cell *head = new Cell;//链表头用new建立
head->next = NULL;
head->value = vector[0];
Cell *curr = head;//取头指针,之前的 head用于返回
for(int i=0;i<vector.size(); i++){
Cell *newCell = new Cell;
newCell->next = NULL;
newCell->value = vector[i];
curr->next = newCell;
newCell = curr;
}
return head;
}
Cell * ConvertToListRealRecur(Vector<int> &vector, int index)
{
if(index >= vector.size())
return NULL;
Cell *curr = new Cell;
curr->value = vector[index];
curr->next = ConvertToListRealRecur(vector, index + 1);
return curr;
}
Cell * ConvertToListRecur(Vector<int> vector)
{
return ConvertToRealRecur(vector, 0);
}
b)链表操作
int SumListIter(Cell *list){
int sum = 0;
Cell *curr = list;//curr指向头指针
whlie(curr != NULl){
sum += curr->value;
curr = curr->next;
}
return sum;
}
int SumListRecur(Cell *list)
{
if(list == NULL)
return 0;
else
return list->value + SumListRecur(list->next);//链表递归经典操作
}
Problem 5: Linked List Trace
实现的功能就是把链表最后一个提到第一个,果然学指针最好的例子还是链表
//Link List Trave
void PopRocks(Cell * & mikey)//&传递,用于改变头指针
{
Cell *ptr;
for (ptr = mikey; ptr->next != NULL; ptr = ptr->next)//将指针传递到结尾
{
/* Note: loop body intentionally left empty */ //想不到把,空循环
}
ptr->next = mikey;//将结尾连到开头
ptr = ptr->next;//移到原来头指针
mikey = mikey->next;//把原来的第二个数变成头指针
ptr->next = NULL;//把原来的第一个指向空指针,即变成结尾
}
Problem 6: Append
记得以前数据结构老师讲过这个例子,怀念
void Append(Cell *& first,Cell * second){
if(first == NULl)
{
first = second; //这就是为什么之前first要用&传递,因为当first为空时,first的头指针会改变
}
else{
Append(first->next,second);//卧槽,亮瞎有木有
}
}