C++ 双链表练习,实现球在屏幕中滚动,排坑
#include <stdio.h> #include <stdlib.h> #include <easyx.h> //定义一个双链表节点 struct Node { int x; //数据 int y; int z; Node* next; //下个数据 Node* last; //上个数据 }; //定义list存放node指针 struct List { int size; //存放node节点的大小 Node* head; //指针指向头节点 Node* tail; //指针指向尾节点 }; //初始化双链表节点 Node* init_node(int x,int y) { Node* temp = (Node*)malloc(sizeof(Node)); temp->x = x; temp->y = y; temp->z = 1; temp->next = temp->last = NULL; return temp; } //初始化双链表 List* init_list() { List* temp = (List*)malloc(sizeof(List)); temp->head = NULL; temp->tail = NULL; temp->size = 0; return temp; } //节点的链接传参,第一个参数数据在前,第二个参数数据在后 void link_node(Node* n1, Node* n2) { n1->next = n2; n2->last = n1; } //双链表链接 List* push_head(List* list, Node* n1) { if (list->size == 0) { list->head = n1; //双链表第一次添加节点时,此时双链表中只有一个元素,list的头指针和尾指针都指向一个链表, list->tail = list->head; list->size = 1; } else { link_node(n1, list->head); list->head = n1; list->size++; } return list; } //从头开始双链表 void list_head_printf(List* list) { if (list->head == NULL) { printf("双链表为空!\n"); return; } else { printf("双链表输出从头部开始输出:"); for (Node *temp = list->head; temp != NULL; temp = temp->next) { printf("%d", temp->x); if (temp == list->tail) printf("\n"); else printf(" "); } } } void push_end(List* data, Node*temp1) //双链表尾插 { List* temp = data; if (temp->head == NULL) { temp->head = temp1; temp->tail = temp->head; temp->size = 1; return; } else { link_node(temp->tail, temp1); temp1->last = temp->tail; //将temp1的前驱挂在尾节点上, temp->tail = temp1; //尾节点的值现在指向temp1 temp->size++; return; } } void del_node(List* list, int num) //双链表删除某个位置的节点 传参:1.双链表节点,2,需要删除的位置 { Node* tt = (Node*)malloc(sizeof(Node)); //动态申请一个结构体指针用于free对象 if (list->head == NULL) //若双链表为空则直接返回 { printf("双链表为空!\n"); return; } if (list->size < num) //判断查找的位置是否和空间大小范围内 { printf("双链表不存在该位置!\n"); return; } if (list->size == 1) //判断删除双链表节点时,双链表只有1个节点 { tt = list->head; free(tt); list->head = list->tail = NULL; list->size = 0; return; } if (list->size == 2) //判断删除双链表节点时,双链表只有2个节点 { Node* temp = (Node*)malloc(sizeof(Node)); temp = list->tail; free(temp); list->head->next = NULL; list->tail = list->head; list->size--; return; } if (list->size > 2) //判断删除双链表节点时,双链表只有2个以上个节点 { int n = 1; for (Node* temp = list->head; temp->next != NULL; temp = temp->next) //循环遍历双链表节点 { if (n == num) //找到当前需要删除的节点 { if (temp->next == NULL) //判断要删除的节点位置是否是在最后, { tt = temp; temp = temp->last; list->tail = temp; free(tt); list->size--; return; } else { tt = temp; link_node(temp->last, temp->next); free(tt); list->size--; return; } } n++; } } } int main() { initgraph(600, 600); List* list = init_list(); for (int i = 1; i <= 10; i++) { push_end(list, init_node(i * 50, i * 50)); } int a = 1; while (1) { cleardevice(); BeginBatchDraw(); for (Node* temp=list->head; temp!=NULL;temp=temp->next) { for (Node* temp = list->head; temp != NULL; temp = temp->next) { if (temp->z == 1) { circle(temp->x, temp->y++, 20); if (temp->y + 33 >= 600) temp->z = 0; } if (temp->z == 0) { circle(temp->x, temp->y--, 20); if (temp->y - 33 <= 30) temp->z = 1; } } } EndBatchDraw(); Sleep(20); } closegraph(); return 0; }
目前遇到的问题是,在图形界面画图的时候,使用一个局部变量定义一个变量为0和1,用if语句判断双链表结构成员 y的值来控制球移动的坐标,但是会出现球在界面中不会整齐的滚动,但是将这个变量定义在双链表节点成员中时,则球会按照设定的方式在屏幕中整齐的滚动,目前原因未知。
方法一可以达成功能实现,但是 方法二无法达成功能实现
//方法一: while (1) { cleardevice(); BeginBatchDraw(); for (Node* temp=list->head; temp!=NULL;temp=temp->next) { for (Node* temp = list->head; temp != NULL; temp = temp->next) { if (temp->z == 1) { circle(temp->x, temp->y++, 20); if (temp->y + 33 >= 600) temp->z = 0; } if (temp->z == 0) { circle(temp->x, temp->y--, 20); if (temp->y - 33 <= 30) temp->z = 1; } } } EndBatchDraw(); Sleep(20); } //方法二: int a = 1; while (1) { cleardevice(); BeginBatchDraw(); for (Node* temp=list->head; temp!=NULL;temp=temp->next) { for (Node* temp = list->head; temp != NULL; temp = temp->next) { if (a == 1) { circle(temp->x, temp->y++, 20); if (temp->y + 33 >= 600) a = 0; } if (a == 0) { circle(temp->x, temp->y--, 20); if (temp->y - 33 <= 30) a = 1; } } } EndBatchDraw(); Sleep(20); }
目前已经找到问题,需要判断每个球在y轴坐标的变化,那么这时需要在双链表成员中为该双链表定义一个标识,每当球的y轴坐标发生变化时,也就是对应的temp->y的值来判断是否在图形图界面坐标范围内,
这样才能实现每一个球可以自由的在界面中移动,如果单纯使用变量在双链表外部定义,则会导致temp->y的值不受界面坐标的控制而发生球不按设定来移动.
困扰了多天的问题,当找到问题并解决时,才发现原理那么简单..