Search code examples
c++c++builder-6

Build the graphic and use linked list


I should make 2 codes that building graphics. I already have 1. It is just building picture:

  double a = LabeledEdit1 -> Text.ToDouble();
  double S = LabeledEdit2 -> Text.ToDouble();
  Series1-> Clear();
  for( float i = -5; i <= 5; i+=S ) {
    float y = exp(i*log(a));
    Series1->AddXY( i , y ,"",clBlue);
  }

But 2nd task is much harder for me. I shoud make new struct

struct K {
  double x;
  double y;
  struct K *next;
};

and then make linked list. Then put points (x,y) to StringGrid and then build the grapfic. I made some pieces of code, but it doesnt work correctly. Need help.

  K* head = 0;
  K* curr = 0;
  K* vyv;
  double x = 1;
  double y;
  double a = LabeledEdit1 -> Text.ToDouble();
  double S = LabeledEdit2 -> Text.ToDouble();
  int i=0;
  for (i = 0; i < 500; ++i) {
    if (i==0) {
      y = exp(x*log(a));
      head = (K*) malloc(sizeof K);
      head->x = x;
      head->y = y;
      head->next = NULL;
    }
    else {
      y = exp(x*log(a));
      curr = (K*) malloc(sizeof K);
      curr->x = x;
      curr->y = y;
      curr->next = NULL;
    }
    x++;
  }
  vyv = head;
  i = 0;
  int l = 0, I = 0;
  while(vyv){
    x = vyv->x;
    StringGrid1->Cells[i][0] = x;
    y = vyv->y;
    StringGrid1->Cells[i][1] = y;
    Series1->AddXY( i , y ,"",clBlue);
    vyv = vyv->next;
    ++i;
  }

Solution

  • Your first loop is not linking the nodes together, so they all have a next value of NULL, thus your second loop runs only 1 iteration (for the head node).

    And you should also be using new instead of malloc().

    Try this instead:

    K* head = 0;
    K* curr = 0;
    K* last = 0;
    double x = 1;
    double y;
    double a = LabeledEdit1 -> Text.ToDouble();
    double S = LabeledEdit2 -> Text.ToDouble();
    int i;
    for (i = 0; i < 500; ++i) {
        y = exp(x*log(a));
        curr = new K;
        curr->x = x;
        curr->y = y;
        curr->next = NULL;
        if (!head) head = curr;
        if (last) last->next = curr;
        last = curr;
        x++;
    }
    curr = head;
    i = 0;
    int l = 0, I = 0;
    while(curr){
        x = curr->x;
        StringGrid1->Cells[i][0] = x;
        y = curr->y;
        StringGrid1->Cells[i][1] = y;
        Series1->AddXY( i , y ,"",clBlue);
        curr = curr->next;
        ++i;
    }
    

    And do not forget to free the nodes when you are done using them:

    curr = head;
    while(curr){
        K *next = curr->next;
        //...
        delete curr;
        curr = next;
    }
    

    With that said, you should use the std::list class instead, let it handle the memory management for you:

    #include <list>
    
    struct K {
        double x;
        double y;
    };
    
    std::list<K> myList;
    
    double x = 1;
    double y;
    double a = LabeledEdit1 -> Text.ToDouble();
    double S = LabeledEdit2 -> Text.ToDouble();
    int i;
    for (i = 0; i < 500; ++i) {
        y = exp(x*log(a));
        K curr;
        curr.x = x;
        curr.y = y;
        myList.push_back(curr);
        x++;
    }
    i = 0;
    int l = 0, I = 0;
    for(std::list<K>::iterator iter = myList.begin(); iter != myList.end(); ++iter)
    {
        x = iter->x;
        StringGrid1->Cells[i][0] = x;
        y = iter->y;
        StringGrid1->Cells[i][1] = y;
        Series1->AddXY( i , y ,"",clBlue);
        ++i;
    }