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的值不受界面坐标的控制而发生球不按设定来移动.

困扰了多天的问题,当找到问题并解决时,才发现原理那么简单..

原文地址:https://www.cnblogs.com/shenji/p/12563276.html

时间: 2024-10-14 06:03:47

C++ 双链表练习,实现球在屏幕中滚动,排坑的相关文章

双链表的实现

双链表:可以从一个表结点出发,在线性表中随意访问它的前驱结点和后继结点,双链表有两个指针. 双链表结template<class Elem> class Link   private:       static Link<Elem>* freelist ;//Head of the freelis   public: Elem element;//value for this node Link *next;//pointer to next node in list Link *

优先双链表

题目: 设有一个双链表,每个结点中除有prior,data和 next这3个域外,还有一个访问频度域 freq,在链表被启用前其值均初始化为0.每当在在链表上进行一次查找操作Locate(L, x)时,令元素值为x的结点中的freq域的值增加1,并使此链表中的结点保持按访问频度域递减的顺序排列,以便使频繁访问的结点总是靠近表头 (1)首先创建一个双链表. (2) 设计一个符合上述要求的Locate(L, x)函数. (3) 具有输出显示访问频度功能. (4) 要求程序通过一个主菜单进行控制,在主

1216.1——双链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.一般我们都构造双向循环链表. typedef struct node{ struct node *pre;   //前驱指针 int age; struct node *next;  //后驱指针 }Node; int main(int argc, const char * argv[]) { Node * phead =

双链表优先队列ADT的实现与测试

源代码如下: #include <stdlib.h> #include <stdio.h> typedef struct pq* PQ; typedef struct PQnode* PQlink; struct Item{int data;char c;}; struct PQnode{Item key;PQlink prev,next;}; struct pq{PQlink head,tail;}; PQ PQinit(){ PQ pq = (PQ)malloc(sizeof*

双链表删除/插入节点

//双链表删除节点 dnode *del(dnode *head, int num) { dnode *p1, *p2; p1 = head; while (num != p1->data && p1->next != NULL) { p1 = p1->next; } if (num == p1->data) { if (p1 == head) { head = head->next; head->pre = NULL; free(p1); } else

redis源码分析(3)-- 基本数据结构双链表list

一.双链表结构 redis中实现的双链表结构体如下: 1 typedef struct list { 2 listNode *head; # 链表头 3 listNode *tail; # 链表尾 4 void *(*dup)(void *ptr); # 复制链表函数 5 void (*free)(void *ptr); # 释放节点函数 6 int (*match)(void *ptr, void *key); # 匹配函数 7 unsigned long len; # 链表节点个数 8 }

线性表—双链表

1.基础知识 a.双链表结点的结构:其由前序元素地址,数据域,后继元素地址组成. b.双链表结点的连接方法:先声明该结点,可以在内部也可以利用其特性来表明前序结点和后继结点是什么,之后同时还需要说明"其前序结点的后继地址为该结点"和"其后继结点的前序地址为该结点.(本质:双向) 2.循环双链表的实现 线性表接口LList package com.clarck.datastructure.dlinked; /*** 线性表接口LList,描述线性表抽象数据类型,泛型参数T表示数

约瑟夫问题 双链表实现

<span style="color:#cc33cc;"> /********************************* author : Grant Yuan algorithm; 双链表. time :2014/10/3 20:38 *********************************/ #include<iostream> #include <cstdio> #include<cstring> #include

双链表&amp;链表合并&amp;多项式相加算法

//单链表的合并 //链表合并 //两个链表必须是有序的 #define Maxsize 5 typedef  int elemtype; typedef struct linklist { elemtype data; struct linklist *next; }Linklist; //建立链表1 Linklist *CreateList1 () { int i,data ; Linklist *head, *p, *q; head=p=(Linklist  *)malloc(sizeof