将链接列表中的第一个项目移动到结束C ++

时间:2015-02-10 19:25:30

标签: c++ linked-list

我需要将链表中的第一项移到列表的末尾。我的问题是我进入无限循环。当我删除无限循环(tail -> link != NULL;在for循环中)的原因时,我得到一个seg错误。因此,寻找有关如何使此代码工作的想法。

#include <iostream>
#include <string>
using namespace std;

struct Node
{
  string data;
  Node *link;
};

class Lilist
{
  public:
    Lilist() {head = NULL;}
    void add(string item);
    void show();
    void move_front_to_back();
    Node* search(string target);

  private:
    Node *head;
};

int main()
{
  Lilist L1, L2;
  string target;

  L1.add("Charlie"); //add puts a name at the end of the list
  L1.add("Lisa");
  L1.add("Drew");
  L1.add("Derrick");
  L1.add("AJ");
  L1.add("Bojian");

  cout << "Now showing list One:\n";
  L1.show(); // displays the list (This function displayed the list properly)
  cout << "\n";

  L1.move_front_to_back();
  L1.move_front_to_back();
  L1.show();
  cout << "\n";

  return(0);
}


void Lilist::add(string item)
{
  Node *temp;
  if(head == NULL)
  {
    head = new Node;
    head -> data = item;
    head -> link = NULL;
  }
  else
  {
    for(temp = head; temp -> link != NULL; temp = temp -> link)
        ;
    temp -> link = new Node;
    temp = temp -> link;
    temp -> data = item;
    temp -> link = NULL;
  }
}

void Lilist::show()
{
  for(Node *temp = head; temp != NULL; temp = temp -> link)
    std::cout << temp -> data << " ";
}

void Lilist::move_front_to_back()
{
  Node *temp;
  Node *tail;

  temp = head;

  for(tail = head; tail != NULL; tail = tail -> link)
    ;

  head = head -> link;
  tail -> link = temp;
  temp -> link = NULL;
}

2 个答案:

答案 0 :(得分:2)

问题在于你如何计算tail。请注意这一点(为简洁省略了不相关的行):

for(tail = head; tail != NULL; tail = tail -> link)
  ;
tail -> link = temp;

请注意,for循环只会在tailNULL后终止。然后,您取消引用tail ...这是空的。

所以改变for循环条件:

for (tail = head; tail->link != NULL; tail = tail->link)
  ;

这将找到列表中的最后一个元素,而不是从末尾流出。

[Live example]

答案 1 :(得分:1)

Angew已经解释了原始代码失败的原因。我建议采用另一种方法 - 为Lilist成员提供与其tail成员一起管理的head成员。然后,您无需在需要时随时寻找tail,您始终可以确切地知道当前Node tail是哪个,例如:

#include <iostream>
#include <string>

using namespace std;

struct Node
{
    string data;
    Node *next;

    Node(string s);
};

class Lilist
{
public:
    Lilist();
    ~Lilist();
    void add(string item);
    void show();
    void move_front_to_back();
    Node* search(string target);

private:
    Node *head;
    Node *tail;
};

Node::Node(string s)
    : data(s), next(NULL)
{
}

Lilist::Lilist()
    : head(NULL), tail(NULL)
{
}

Lilist::~Lilist()
{
    for(Node *temp = head; temp != NULL; temp = temp->next)
        delete temp;
}

void Lilist::add(string item)
{
    Node *temp = new Node(item);

    if (head == NULL)
        head = temp;

    if (tail != NULL)
        tail->next = temp;

    tail = temp;
}

void Lilist::show()
{
    for(Node *temp = head; temp != NULL; temp = temp->next)
        cout << temp->data << " ";
}

void Lilist::move_front_to_back()
{
    if (head == tail)
        return;

    Node *temp = head;

    head = temp->next;
    temp->next = NULL;

    tail->next = temp;
    tail = temp;
}

Node* Lilist::search(string target)
{
    for(Node *temp = head; temp != NULL; temp = temp->next)
    {
        if (temp->data == target)
            return temp;
    }
    return NULL;
}