c++ 如何在自定义图中添加一个函数,删除具有1个传入边和1个传出边的顶点?[关闭]

pgx2nnw8  于 2023-05-24  发布在  其他
关注(0)|答案(1)|浏览(221)

已关闭,此问题需要更focused。目前不接受答复。
**想改善这个问题吗?**更新问题,使其仅通过editing this post关注一个问题。

7小时前关闭
Improve this question
我创建了一个自定义图,而不使用STL,具有基本功能,如添加顶点,在它们之间添加边,可视化图形和删除顶点。但是现在我想修改代码,使其只删除具有1条传入边和1条传出边的顶点。
说实话我不知道该怎么做,所以如果有人能帮助我,我会非常高兴的!
感谢您的评分
下面是我现在创建的代码:

#include<iostream>

using namespace std;

const int n = 10;

struct link {
    char key;
    link* next;
} *G[n];

void init(link* gr[n]) {
    for (int i = 0; i < n; i++)
        gr[i] = NULL;
}

int search_node(link* gr[n], char c) {
    int flag = 0;
    for (int i = 0; i < n; i++)
        if (gr[i])
            if (gr[i]->key == c)
                flag = 1;
    return flag;
}

int search_arc(link* gr[5], char c1, char c2) {
    int flag = 0;
    if (search_node(gr, c1) && search_node(gr, c2)) {
        int i = 0;
        link* p;
        do {
            if ((gr[i] == NULL) || (gr[i] && gr[i]->key != c1))
                i++;
        } while (gr[i]->key != c1);
        p = gr[i];
        while (p->key != c2 && p->next != NULL)  p = p->next;
        if (p->key == c2) flag = 1;
    }
    return flag;
}

void add_node(link* gr[n], char c) {
    if (search_node(gr, c)) {
        cout << "\nVyrhyt veche syshtestvuva\n";
    }
    else {
        int j = 0;
        while (gr[j] && (j < n)) j++;
        if (gr[j] == NULL) {
            gr[j] = new link;
            gr[j]->key = c;
            gr[j]->next = NULL;
        }
        else {
            cout << "\nPrepylvane na strukturata\n";
        }
    }
}

void add_arc(link* gr[n], char c1, char c2) {
    if (search_node(gr, c1) && search_node(gr, c2)) {
        int i = 0;
        link* p;
        while (gr[i]->key != c1)  i++;
        p = new link;
        p->key = c2;
        p->next = gr[i]->next;
        gr[i]->next = p;
    }
    else {
        cout << "\nVryhove ne sushtestvuva";
    }
}

void del_node(link* gr[n], char c) {
    if (search_node(gr, c)) {
        for (int i = 0; i < n; i++) {
            link* p = gr[i], * temp;
            if (p && p->key == c) {
                gr[i] = p->next;
                delete p;
            }
            else {
                while (p && p->next != NULL && p->next->key != c) {
                    p = p->next;
                }
                if (p && p->next != NULL) {
                    temp = p->next;
                    p->next = temp->next;
                    delete temp;
                }
            }
        }
    }
    else {
        cout << "V grafa nqma takyv vryh";
    }
}

void print_menu() {
    cout << "Menu:\n";
    cout << "1. Dobavqne na vryh\n";
    cout << "2. Dobavqne na dyga\n";
    cout << "3. Iztrivane na vryh\n";
    cout << "4. Vizualizirane na grafa\n";
    cout << "5. Izhod\n";
    cout << "Izberete opciq: ";
}

void visualize_graph(link* gr[n]) {
    cout << "Graph Visualization:\n";
    for (int i = 0; i < n; i++) {
        if (gr[i]) {
            cout << gr[i]->key << " -> ";
            link* p = gr[i]->next;
            while (p != NULL) {
                cout << p->key << " -> ";
                p = p->next;
            }
            cout << "NULL\n";
        }
    }
    cout << endl;
}

int main() {
    link* graph[n];
    init(graph);

    char option;
    char c, c1, c2;

    do {
        print_menu();
        cin >> option;

        switch (option) {
        case '1':
            cout << "Vyvedete vryh: ";
            cin >> c;
            add_node(graph, c);
            break;
        case '2':
            cout << "Vyvedete pyrvi vryh na dygata: ";
            cin >> c1;
            cout << "Vyvedete vtori vryh na dygata: ";
            cin >> c2;
            add_arc(graph, c1, c2);
            break;
        case '3':
            cout << "Vyvedete vryh za iztrivane: ";
            cin >> c;
            del_node(graph, c);
            break;
        case '4':
            visualize_graph(graph);
            break;
        case '5':
            cout << "Izhod ot programata.\n";
            break;
        default:
            cout << "Nevalidna opciq!\n";
            break;
        }
    } while (option != '5');

    return 0;
}
qyyhg6bp

qyyhg6bp1#

删除节点的代码存在问题。

void del_node(link* gr[n], char c) {
    if (search_node(gr, c)) {
        for (int i = 0; i < n; i++) {
            link* p = gr[i], * temp;
            if (p && p->key == c) {
                gr[i] = p->next;
                delete p;
            }

所以:

link* p = gr[i]

这一行将p设置为指向保存要删除的节点的图数组的元素
然后

gr[i] = p->next;

用第一个相邻节点替换要删除的节点。我猜这不是你的本意
然后

delete p;

这一行将删除与要删除的节点相邻的第一个节点。这会让你的图变得混乱。
下面是一些从图中删除节点的代码

void del_node(link *gr[n], char c)
{
    // loop over nodes in graph
    for (int i = 0; i < n; i++)
    {
        auto *p = gr[i];
        if (!p) {
            // undefined node
            continue;
        }

        if (p->key == c)
        {
            // remove node from graph
            gr[i] = 0;
            continue;
        }

        if (!p->next)
        {
            // no adjacent nodes
            continue;
        }

        // search adjacency list for deleted node
        while (true)
        {
            if (p->next->key == c) {
                // remove node from adjacency list
                p->next = p->next->next;
            }

            if (!p->next)
                break;
            p = p->next;
        }
    }
}

下面是单元测试代码

void test()
{
    link *graph[n];
    init(graph);

    add_node(graph, 'a');
    add_node(graph, 'b');
    add_node(graph, 'c');
    add_arc(graph, 'a', 'b');
    add_arc(graph, 'a', 'c');
    std::cout << "test ";
    visualize_graph(graph);

    del_node(graph, 'b');

    std::cout << "test delete b ";
    visualize_graph(graph);
}

测试输出为

test Graph Visualization:
a -> c -> b -> NULL
b -> NULL
c -> NULL

test delete b Graph Visualization:
a -> c -> NULL
c -> NULL

下面是删除入度和出度为1的音符的代码

void deleteNodes1in1out(link *gr[n])
{
    std::vector<char> marked;
    for (int i = 0; i < n; i++)
    {
        auto *p = gr[i];
        if (!p)
            continue;
        if( outDegree(gr,p->key) == 1 &&
            inDegree(gr,p->key) == 1 )
            marked.push_back( p->key);
    }
    for( char c : marked )
    {
        del_node(gr,c);
    }
}

完整的代码在https://github.com/JamesBremner/so76295213

相关问题