简体   繁体   English

C二维数组到链接列表

[英]C Two Dimensional Array into Linked List

So I'm still trying to wrap my head around linked lists in C. They are.. mind-boggling to me right now because I have yet to fully understand pointers, let alone pointers to pointers, and dynamic memory allocation that linked lists require. 所以我仍在努力用C语言编写链接列表。它们对我来说真是令人难以置信,因为我还没有完全理解指针,更不用说指向指针的指针了,以及链接列表需要的动态内存分配。

I'm trying to create a two dimensional array with independent height, and width values. 我正在尝试创建一个具有独立的高度和宽度值的二维数组。 At most they would be 30x30. 最多为30x30。 I have a two dimensional array let's call it arr[x][y]. 我有一个二维数组,我们称它为arr [x] [y]。 arr[x][y] is filled with values of integers ranging from -2 to 1, how would I transfer this two dimensional array into a linked list? arr [x] [y]填充了从-2到1的整数值,我如何将这个二维数组传输到链接列表中? How would I then access values from this linked list on whim? 然后,我怎么会一时兴起从此链接列表中访问值? I'm very confused, and any help would be appreciated. 我很困惑,任何帮助将不胜感激。 I'm looking through tutorials as we speak. 我正在浏览我们讲的教程。

Additionally this is supposed to be a sort of stack linked list where I could call functions such as push(pushes a new value to the top of the linked list), pop(pops a value from the top of the linked list), top(returns the value most recently pushed onto the stack), isEmpty(checks if the stack is empty). 另外,这应该是一种堆栈链接列表,我可以在其中调用诸如push(将新值推到链接列表的顶部),pop(从链接列表的顶部弹出一个值),top(返回最近推送到堆栈上的值),isEmpty(检查堆栈是否为空)。

I don't need any full code, but code would be helpful here. 我不需要任何完整的代码,但是这里的代码会有所帮助。 I just need an understanding though of Linked Lists, and how to implement these sort of functions. 我只需要了解链接列表,以及如何实现这些功能。

Additionally here is the assignment that this is related to: Assignment 此外,这是与此相关的作业作业

It's a maze solver, I've already done code for analyzing a ascii picture into integer values for the two dimensional array. 这是一个迷宫求解器,我已经完成了将二维图片解析为整数值的代码。 And as stated above that is what I need help with. 如上所述,这就是我需要帮助的地方。

提示:从您的分配来看,堆栈不应该完全表示数组,而是表示您动态构建的路径,以找到从迷宫的起始位置到迷宫的目标位置的方法。

Basically you need to create a link list, whose each node is the head of another list contained as a member (which conceptually grows downwards), along with a usual next pointer in the list. 基本上,您需要创建一个链接列表,该列表的每个节点都是作为成员包含的另一个列表(概念上向下增长)的头部,以及列表中通常的下一个指针。

For accessing an element like 2D array such as arr[3][4], you need to walk the first list while keeping a count of yand then move downward counting x Or you could do vice versa. 要访问诸如arr [3] [4]之类的2D数组之类的元素,需要遍历第一个列表,同时保持y的计数,然后向下移动x计数,或者反之亦然。

This is a common data structure assignment which goes by the name "multi stack or multi queue" which if implemented by lists gives what you are looking for. 这是一种常见的数据结构分配,其名称为“多堆栈或多队列”,如果由列表实现,则将为您提供所需的内容。

struct Node
{
    int data;
    struct Node *next;
    struct Node *head; // This head can be null initially as well as for the last node in a direction
};

First of all you need to define the proper structure.The first times it will be easier for you to create a list that terminates when the pointer to the next node is NULL.Afterwards you will discover lists with sentinel, bidirectional lists and things that now may seem too complicated. 首先,您需要定义适当的结构。第一次创建列表时会更容易,该列表在指向下一个节点的指针为NULL时终止,然后您将发现带有前哨,双向列表以及现在的东西的列表。可能看起来太复杂了。
For example that's a structure: 例如,这是一个结构:

typedef struct __node
{
    int info;
    struct __node* next;
}node;

typedef node* list;

This time let's assume that list and node are the same thing, you will find more precise to separate the concept of list than the concept of node, and for example you may store in the list it's length (avoiding to count everytime all the nodes), but for now let's do it that way. 这次我们假设列表和节点是同一件事,您将发现分隔列表的概念比节点的概念更为精确,例如,您可以将列表的长度存储在列表中(避免每次计算所有节点时都进行计数) ,但现在让我们那样做。
You initialize the list: 您初始化列表:

list l=NULL;

So the list contains zero nodes, to test if it's empty you just see if the pointer is NULL. 因此,列表包含零个节点,要测试其是否为空,只需查看指针是否为NULL。
Add a new element: 添加一个新元素:

if(NULL==l)
{
    l=(node*)malloc(sizeof(node));
    l->next=NULL;
    l->info=0;
}

Now the list contains zero nodes, create a function to add a new node: 现在列表包含零个节点,创建一个函数以添加一个新节点:

void pushBack(list* listPointer, int info)
{
    if(NULL==*listPointer)
    {
        *listPointer=(node*)malloc(sizeof(node));
        (*listPointer)->info=info;
    }
    else
    {
        node* ptr=l;
        while(ptr->next!=NULL)
            ptr=ptr->next;
        ptr->next=(node*)malloc(sizeof(node));
        ptr->info=info;
    }
}

You could also gain efficiency adding the elements in front.Or optimize the code by returning the added element, so that you don't have to find the last element everytime.I leave this to you.Now let's call the pushBack function for every element of the array: 您还可以在前面添加元素来提高效率,或者通过返回添加的元素来优化代码,这样就不必每次都找到最后一个元素了,现在我就把它留给您,现在让我们为每个元素调用pushBack函数的数组:

for(int i=0; i<N; i++)
{
    pushBack(l,arr[i]);
}

That's all, learn your way to implement linked lists. 就是这样,了解您实现链表的方式。

You're not supposed to convert the whole array into a linked list, you're only supposed to convert the best path into a linked list. 您不应将整个数组转换为链表,而应仅将最佳路径转换为链表。 You'd do this by brute force, trying directions and backtracking when you ran into dead ends. 当您遇到死胡同时,您将用蛮力做到这一点,尝试方向和回溯。

Your path, the linked list, would need to look something like this: 您的路径(链接列表)需要看起来像这样:

struct PathNode
{
    int coordX, coordY;
    PathNode * next, * prev;
}

If I remember later, I'll draw a picture or something of this structure and add it to the post. 如果我以后记得,我会画一张图片或这种结构的东西,并将其添加到帖子中。 comment on this post in a few hours to attract my attention. 请在几个小时后对此信息发表评论,以吸引我的注意力。

The list would always contain a starting point, which would be the first node in the list. 该列表将始终包含一个起点,该起点将是列表中的第一个节点。 As you moved to other positions, one after the other, you'd push them onto the end of the list. 当您一个接一个地移到其他位置时,可以将它们推到列表的末尾。 This way, you could follow your path from your current position to the beginning of the maze by simply popping elements off of the list, one by one, in order. 这样,您可以简单地按顺序从列表中逐个弹出元素,从而遵循从当前位置到迷宫开始的路径。

This particular linked list is special in that it's two way: it has a pointer to both the next element and the previous one. 此特定的链表的特殊之处在于它有两种方式:它具有指向下一个元素和上一个元素的指针。 Lists with only one of the two are called singly linked lists, this one with both is called a doubly linked list. 只有两个列表之一的列表称为单链接列表,而这两个列表都称为双链接列表。 Singly linked lists are one way only, and can only be traversed in one direction. 单链列表只是一种方式,只能在一个方向上遍历。

Think of your linked list as giant pile of strings, each with a starting end and a finishing end. 可以将链接列表视为一堆巨大的字符串,每个字符串都有一个起始端和一个结束端。 As you walk through the maze, you tie a string at every node you visit and bring an end with you to the next square. 在迷宫中穿行时,您要在访问的每个节点上系一根绳子,并随身带到下一个广场。 If you have to backtrack, you bring the string back with you so it no longer points to the wrong square. 如果必须回溯,可以将字符串带回去,这样它就不再指向错误的正方形。 Once you find your way to the end of the maze, you will be able to trace your steps by following the string. 一旦找到迷宫的尽头,就可以通过跟随字符串来跟踪步伐。

Could you just explain what -> means exactly? 您能解释一下->到底是什么意思吗?

-> is an all-in-one pointer dereference and member access operator. ->是多合一指针取消引用和成员访问运算符。 Say we have: 说我们有:

PathNode * p = malloc(sizeof(*p));
PathNode q;

We can access p's and q's members in any of the following ways: 我们可以通过以下任意方式访问p和q的成员:

(*p).coordX;
q.coordX;
p->coordX;
(&q)->coordX;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM