【问题标题】:C++ circular linked list deletion, counts start at the next nodeC++循环链表删除,从下一个节点开始计数
【发布时间】:2017-07-27 05:07:04
【问题描述】:

我不知道如何在循环链接列表中删除。例如,头部是 B,因此列表将从“B、C、D、E、A”开始。第一个节点将始终从 1-5 中选择一个数字,我使用计数器不断减少该数字,例如,如果“B”选择了 3,则计数将开始到它的下一个节点“C”,因此从“C”开始计数,一旦“E”被消除,我们将不得不消除“E”。

新的 head aka picker 将在被淘汰的节点之后开始到下一个节点,所以下一组节点将变为“A,B,C,D”,这个函数必须重复,直到只有 1 个最后的常设节点.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include <string>
#include <ctime>

using namespace std;

/*
* Node Declaration
*/
struct node
{
    string name;
    struct node *next;
};

node *t, *head;
node *ex;
int paper;
int ctr = 5;
int num;

void create(string sname)
{
    node *n = new node;
    n->name = sname;
    if (head == NULL)
    {
        head = n;
        t = n;
    }
    else
    {
        t->next = n; // connects the nodes
        t = t->next; // moves the connecter to the t= last
    }
    t->next = head;
}


/*
* Deletion of element from the list
*/
void delete_element(string value)
{
}

//Display Circular Link List

void display()
{
    node *temp = new node;
    temp = head;

    if ((head == NULL) && (t == NULL))
    {
    }

    for (int j = 1; j <= 5; j++)
    {
        cout << temp->name << "\n";
        temp = temp->next;
    }
}

void firstpic()
{
    srand(time(NULL));
    paper = rand() % 5 + 1;
    int fctr = 5;
    bool p1 = 0, p2 = 0, p3 = 0, p4 = 0, p5 = 0;

    if (paper == 1)
    {
        create("A");//1
        fctr--;
    }
    else if (paper == 2)
    {
        create("B");//2
        p2 = 1;
    }
    else if (paper == 3)
    {
        create("C");//2
        p3 = 1;
    }
    else if (paper == 4)
    {
        create("D");//2
        p4 = 1;
    }
    else if (paper == 5)
    {
        create("E");//2
        p5 = 1;
    }

    if (p1) 
    {
        create("B");
        create("C");
        create("D");
        create("E");
    }
    else if (p2) 
    {
        create("C");
        create("D");
        create("E");
        create("A");
    }
    else if (p3) 
    {
        create("D");
        create("E");
        create("A");
        create("B");
    }
    else if (p4) 
    {
        create("E");
        create("A");
        create("B");
        create("D");
    }
    else if (p5) 
    {
        create("A");
        create("B");
        create("C");
        create("D");
    }
}

void drawn()
{
    node *holder = head;
    ex = holder->next;
    cout << holder->name << " has drawn: " <<num <<endl;
}

int main()
{
    head == NULL;
    t == NULL;
    srand(time(NULL));
    firstpic();
    display();
    num = rand() % ctr + 1;
    drawn();

    system("pause>nul");
    return 0;
}

【问题讨论】:

  • 找到要删除的节点之前的节点nodePrev,以及要删除的节点之后的节点nodeNext,然后将它们连接起来:nodePrev-&gt;next = nodeNext。如果您删除它,您需要验证您是否重置了您的根或head。此外,通常有助于使这些链接列表双向
  • 例如,如果我的头是 (D) 并且列表是这样的 (D,E,A,B,C) 那么我的尾巴是 (C) 对吗?那么D已经画了5,所以从(E)到(D),(D)将被删除。是这样的语法, Void delpos(int pos) { node *prev;节点*下一个;上一页=头; // 注意 head is = D for(int x =0; xnext; } 下一个 = 上一个->下一个; } 这是正确的吗?

标签: c++ circular-list


【解决方案1】:

这里有一些可能适合您的需求:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <ctime>

using namespace std;

/*
* Node Declaration
*/
struct node
{
    string name;
    struct node *next;
};

node *tail, *head;

void addNode(string sname)
{
    node *n = new node;
    n->name = sname;

    if (head == NULL) {
        head = n;
        tail = n;
    } else {
        tail->next = n;    // connects the nodes
        tail = tail->next; // moves the connecter to the t= last
    }
    tail->next = head;
}


/*
* Deletion of element from the list
*/
void removeNode(string value)
{
    // no elements
    if (head == NULL) {
        return;
    }

    node *n = head;
    node *prev = tail;

    // 1 element
    if(n == prev) {
        if(n->name == value) {
            delete n;
            head = tail = NULL;
        }
        return;
    }

    bool found = false;
    // search
    do {
        if(n->name == value) {
            found = true;
            break;
        }
        prev = n;
        n = n->next;
    } while (n != head);

    // no such element
    if(!found) {
        return;
    }

    prev->next = n->next;
    if(n == head) {
        head = n->next;
    } else if(n == tail) {
        tail = prev;
    }
    delete n;
}

void displayList()
{
    if (head == NULL) {
        cout << "empty!" << endl;
        return;
    }

    node *n = head;

    do {
        cout << n->name << "\n";
        n = n->next;
    } while (n != head);
    cout << endl;
}

void createList()
{
    const int count = 5;
    std::string names[count] = {"A", "B", "C", "D", "E"};

    int nameIndex = rand() % count;

    for(int i = 0; i<count; ++i) {
        nameIndex += 1;
        nameIndex %= count;
        addNode(names[nameIndex]);
    }
}

int main()
{
    srand(time(NULL));

    head = NULL;
    tail = NULL;

    createList();
    displayList();
    removeNode("A");
    displayList();
    removeNode("A");
    displayList();
    removeNode("E");
    displayList();
    removeNode("B");
    displayList();
    removeNode("C");
    displayList();
    removeNode("D");
    displayList();

    system("pause>nul");

    return 0;
}

请注意,在删除节点期间,您应该注意以下情况:

  • 无元素案例
  • 要删除的最后 1 个元素
  • 头部缺失
  • 尾部删除

另外,永远不要像在 firstpic() 函数中那样做:这是一种痛苦的做法。 drawn() 函数似乎没有做任何有意义的事情,但它不在问题的范围内。

【讨论】:

  • 天哪,你是天赐之物,我会研究这个代码,非常感谢,我真的很感激
猜你喜欢
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多