7-1~7-2

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
struct Node {
	DataType	  coef;
	 DataType     exp;
	struct Node*  next;
};
typedef struct Node  *PNode;
typedef struct Node  *LinkList;
LinkList SetNullList_Link()
{
	LinkList head = (LinkList)malloc(sizeof(struct Node));
	if (head != NULL) head->next = NULL;
	else printf("alloc failure");
	return head;
}

void CreateList(struct Node* head)
{
    DataType coef,exp;
	PNode p = NULL;
	PNode q = head;
	scanf("%d,%d", &coef,&exp);
	while (coef!=0)
	{
		p = (struct Node*)malloc(sizeof(struct Node));
		p->coef = coef;
		p->exp = exp;
		p->next=NULL;
		q->next=p;
		q=p;
		scanf("%d,%d", &coef,&exp);
	}
}
void MoveMaxToTail (LinkList head)
{
    PNode pre,q;
    int tcoef,texp;
    for(pre=head->next;pre->next!=NULL;pre=pre->next)
       for(q=pre->next;q!=NULL;q=q->next)
    {
        if(q->exp<pre->exp)
           {
               tcoef=pre->coef;
               texp=pre->exp;
               pre->coef=q->coef;
               pre->exp=q->exp;
               q->coef=tcoef;
               q->exp=texp;
           }
    }
}
LinkList PolynomialAddition(LinkList head1,LinkList head2)
{
    PNode preA=head1->next,qA=preA->next;
    free(head1);
    PNode preB=head2->next,qB=preB->next;
    free(head2);
    PNode head = (LinkList)malloc(sizeof(struct Node));
    head->next=NULL;
    PNode pre=head;
    while(preA!=NULL&&preB!=NULL)//当链表链表有一个遍历到表尾时结束
    {
        if(preA->exp<preB->exp)//当满足条件时,将preA节点插入新链表
        {
            preA->next=pre->next;
            pre->next=preA;
            preA=qA;
             if(preB==NULL)
                    continue;
            qA=qA->next;
            pre=pre->next;

        }
        else
             if(preB->exp<preA->exp)//当满足条件时,将preB插入新链表
            {
                preB->next=pre->next;
                pre->next=preB;
                preB=qB;
                 pre=pre->next;
                if(preB==NULL)
                    continue;
                qB=qB->next;


            }
            else
              if(preA->coef+preB->coef==0)//当满足条件,书房preA和preB
              {
                 free(preA);
                 preA=qA;
                 if(preA!=NULL)
                 qA=qA->next;
                 free(preB);
                 preB=qB;
                 if(preB!=NULL)
                 qB=qB->next;
              }
              else//当preA->coef+preB->coef≠0时
              {
                preA->coef=preB->coef+preA->coef;
                preA->next=pre->next;
                pre->next=preA;
                preA=qA;
                if(preA!=NULL)
                qA=qA->next;
                pre=pre->next;
                free(preB);
                preB=qB;
                if(preB!=NULL)
                qB=qB->next;

              }
    }//当循环结束时,两条链表遍历不一定就此结束,以为链表长度不一定相同,所以要进行以下操作
    //将链表中未遍历的部分直接接入新链表
    if(preA!=NULL)
        pre->next=preA;
    else
        pre->next=preB;
    return head;
}
void print(LinkList head)
{
    LinkList p;
    p=head->next;
    while(p!=NULL)
    {
        printf("%d,%d ",p->coef,p->exp);
        p=p->next;
    }
}
int main()
{
    LinkList head1;
    LinkList head2;
    LinkList head;
    head1=SetNullList_Link();
    head2=SetNullList_Link();
    CreateList(head1);
    CreateList(head2);
    MoveMaxToTail (head1);
    MoveMaxToTail (head2);
    head=PolynomialAddition(head1,head2);
    print(head);
    return 0;
}

这是一个陷入迷官的老鼠如何找到出口的问题,要求输出老鼠探索出的从入口到出口的路径。老鼠希望尽快地找到出口走出迷官。如果它到达一个死胡同,将原路返回到上一个位置,尝试新的路径。在每个位置上老鼠可以向 4 个方向运动,即上、下、左、右。无论离出口多远,它总是按照这样的顺序尝试,当到达一个死胡同之后,老鼠将进行"回溯"。这种探索路径的回溯过程是最后走的位置要最先返回,因此可以使用栈来保存走过的路径序列。

迷宫可以用一个二维数组 maze[m+2][n+2]表示,数组中的元素或者为0,或者为1.0表示通路,1表示墙,迷宫的四周可以设想为全 1,即为墙。设置入口为 maze[1][1]、出口为 maze[6][6]。为了避免检查是否到达了边界,在迷官四周添加一条取值为 1的边来表示障碍,如图 3-4 所示。

解决迷宫问题有两种策略(一种是深度优先策略,另外一种是广度优先策略。两种策略分别对应栈和队列做辅助数据结构。在本节采用深度优先策略,在 3.11 节采用广度优先策略解决迷宫问题。

在迷宫问题中要找到路径并输出需要解决 3 个问题。

为了让计拿

(1) 从某一个坐标点(x,y)出发如何搜索其相邻位置(g,h)?

为了简化判断,假设迷官四周都是墙,即在四周都赋值为 1 的一条边这样对于任意的位置,与它相邻的位置有 8 个,如图 3-5 所示

为了让计算机对 8个位置按照一定的顺序搜索,不妨假设 8个方向的顺序是从正东按照顺时针,将这 8个方向的位置的坐标放到一个结构数组 direction[8][2]中,数组内容为:

direction[8][2]=((0,1),[1,1},(1,0),(1,-1),(0,-1),(-1,-1),[ -1,0)

数组中给出了相邻位置(g,h)相对于当前位置(x,y)的增量,即:

g=x+direction[i][j]

h= y+ direction[i][j]

假设从当前位置(3,5)向南出发,则:

g=x+ direction[2][0] = 3 + 1 = 4

h= y+ direction[2][1] = 5 + 0 = 5

(2) 如何记录探索过的路径?由于采用了回溯方法,因此设计栈来存放探索过的路径,当不能向前继续探索时从栈中弹出元素。

为了重复使用前面定义好的栈结构,在这里使用两个栈 linkStackX和linkStackY 分别存放行坐标和列坐标。

(3) 如何防止重复探索某位置?

通过设置标志位来识别,初始时各个位置的标志位 mark[][j]-0当探索到某位置后设置 mark[][]=1。

有了上述基本定义,迷宫算法的思路如下:

(1)创建两个空栈 StackX 和 StackY。

(2)将人口 entryX 和 entryY 分别压人栈 StackX和 StackY中

(3) while(栈不空)

1, 取栈顶元素,出栈,当前位置为栈顶元素

2, while(mov< 8),即还存在探索的方向。

a,按照顺时针依次探索各个位置(posX,posY)

b。如果(posX,posY)是出口,输出路径,返回1。

c。如果(posX,posY)是没有走过的通路:

·设置标志位mark[posX][pos=1.

.当前位置进栈。

.将(posX,posY)设置为当前位置

.设置 mov=0。

d,否则(如果(X,Y)是没有走过的通路),mov++

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
struct MAZE_STRU
{
    int size;
    int **data;
};
typedef struct MAZE_STRU Maze;
typedef int DataTye;
struct Node
{
    DataTye data;
    struct Node *next;
};
typedef struct Node *PNode;
typedef struct Node*top,*LinkStack;
LinkStack SetNullStack_Link()
{
    LinkStack top=(LinkStack)malloc(sizeof(struct Node));
    if(top!=NULL)
    {
        top->next=NULL;
    }
    else
    {
        printf("alloc failuer");
    }
    return top;
}
 void Push_Link(LinkStack top,DataTye x)
 {
     PNode p=(PNode)malloc(sizeof(struct Node));
         if(p==NULL)
         {
             printf("alloc failuer");
         }
     else
     {
         p->data=x;
         p->next=top->next;
         top->next=p;
     }
 }
int IsNullStack_Link(LinkStack top)
{
    if(top->next==NULL)
    {
        return 1;
    }
    else
        return 0;
}

void Pop_Link(LinkStack top)
{
    PNode p;
    if(top->next==NULL)
    {
        printf("it is empty stack!");
    }
    else{
        p=top->next;
        top->next=p->next;
        free(p);
    }
}

DataTye Top_Link(LinkStack top)
{
    if(IsNullStack_Link(top)==1)
    {
        printf("if is empty stack");
    }
    else{
        return top->next->data;
    }
}

Maze*InitMaze(int size)
{
    int i;
    Maze*maze=(Maze*)malloc(sizeof(Maze));
    maze->size=size;
    maze->data=(int**)malloc(sizeof(int*)*maze->size);
    for(i=0;i<maze->size;i++)
    {
        maze->data[i]=(int*)malloc(sizeof(int)*maze->size);
    }
    return maze;
}
void ReadMaze(Maze *maze)
{
    int i,j;
    for(i=0;i<maze->size;i++)
    {
        for(j=0;j<maze->size;j++)
        {
            scanf("%d",&maze->data[i][j]);
        }
    }
}
void WriteMaze(Maze*maze)
{
    int i,j;
    printf("迷宫结构如下:\n");
    for(i=0;i<maze->size;i++)
    {
        for(j=0;j<maze->size;j++)
        {
            printf("%5d",maze->data[i][j]);
        }
        printf("\n");
    }
}
int MazeDFD(int entryX,int entryY,int exitX,int exitY,Maze *maze)
{
    int derection[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,1},{-1,-1},{-1,0},{-1,1}};
    LinkStack LinkStackX=NULL;
    LinkStack LinkStackY=NULL;
    int posX,posY;
    int preposX,preposY;
    int **mark;
    int i,j;
    int mov;
    mark=(int**)malloc(sizeof(int*)*maze->size);
    for(i=0;i<maze->size;i++)
    {
        mark[i]=(int*)malloc(sizeof(int)*maze->size);
    }
    for(i=0;i<maze->size;i++)
    {
        for(j=0;j<maze->size;j++)
        {
            mark[i][j]=0;
        }
    }
LinkStackX=SetNullStack_Link();
LinkStackY=SetNullStack_Link();
mark[entryX][entryY]=1;
Push_Link(LinkStackX,entryX);
Push_Link(LinkStackY,entryY);
while(!IsNullStack_Link(LinkStackX))
{
    preposX=Top_Link(LinkStackX);
    preposY=Top_Link(LinkStackY);
    Pop_Link(LinkStackX);
    Pop_Link(LinkStackY);
    mov=0;
    while(mov<8)
    {
        posX=preposX+derection[mov][0];
        posY=preposY+derection[mov][1];
        if(posX==exitX&&posY==exitY)
        {
            Push_Link(LinkStackX,preposX);
            Push_Link(LinkStackY,preposY);
            printf("%d %d;",exitX,exitY);
        while(!IsNullStack_Link(LinkStackX))
        {
            posX=Top_Link(LinkStackX);
            posY=Top_Link(LinkStackY);
            printf("%d %d;",posX,posY);
            Pop_Link(LinkStackX);
            Pop_Link(LinkStackY);
        }
        return 1;
        }
    if(maze->data[posX][posY]!=1&&mark[posX][posY]!=1)
    {
        mark[posX][posY]=1;
        Push_Link(LinkStackX,preposX);
        Push_Link(LinkStackY,preposY);
        preposX=posX;
        preposY=posY;
        mov=0;
    }
    else
        mov++;
    }
}
return 0;
}
 int main()
 {
     Maze* maze;
     int mazeSize;
     int entryX,entryY,exitX,exitY;
     int find=0;
     scanf("%d",&mazeSize);
     maze=InitMaze(mazeSize);
     ReadMaze(maze);
     scanf("%d%d%d%d",&entryX,&entryY,&exitX,&exitY);
     find=MazeDFD(entryX,entryY,exitX,exitY,maze);
     if(find==0)
     {
         printf("找不到路径!");
     }
     return 0;
}
相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习