06-图1. List Components (25) (邻接表实现)

繁难的二逼邻接表法  为了不拉低智商请勿模仿

#include <stdio.h>
#include <malloc.h>
#include <queue>

using namespace std;

const int MAXSIZE = 1000;

typedef int ElementType;

struct ListNode
{
    ElementType  Data;
    ListNode *Next;
};

ListNode* CreateList(int data = -1)
{
    ListNode* p = (ListNode*) malloc(sizeof(ListNode));
    p->Next = NULL;
    p->Data = data;
    return p;
}

int Length(ListNode* const ptrL)
{
    ListNode* p = ptrL;
    int i = -1;
    while(p)
    {
        p = p->Next;
        i++;
    }
    return i;
}

ListNode* FindKth(int k, ListNode* ptrL)
{
    ListNode* p = ptrL;
    int i = 0;
    while (p != NULL && i < k)
    {
        p = p->Next;
        i++;
    }
    return p;
}

ListNode* Find(ElementType X, ListNode* ptrL)
{
    ListNode* p = ptrL;
    while (p != NULL && p->Data != X)
    {
        p = p->Next;
    }
    if (p == NULL)
    {
        //printf("%d : NOT FOUND !\n", X);
    }
    return p;
}

ListNode* InsertListNode(ElementType X, int i,  ListNode* const ptrL)
{
    if (i == 1)
    {
        ListNode* p = (ListNode*)malloc(sizeof(ListNode));
        p->Data = X;
        p->Next = ptrL->Next;
        ptrL->Next = p;
        return ptrL;
    }
    ListNode* p = FindKth(i - 1, ptrL);
    if (p == NULL)
    {
        printf("Wrong parameter %d", i);
        return p;
    }
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
    newNode->Data = X;
    newNode->Next = p->Next;
    p->Next = newNode;
    return ptrL;
}

ListNode** CreateListGraph(int size)
{
    ListNode** graph = (ListNode**) malloc(sizeof(ListNode*) * size);
    for (int i = 0; i < size; i++)
    {
        graph[i] = (ListNode*) malloc(sizeof(ListNode));
        graph[i]->Data = i;
        graph[i]->Next = NULL;
    }

    return graph;
}

int FindAscendPos(int item, ListNode* list)
{
    if (list == NULL)
    {
        printf("ERROR : NULL LIST\n");
        return 0;
    }
    ListNode* currentNode = list->Next;
    int i = 1;
    while (currentNode != NULL && currentNode->Data < item)
    {
        i++;
        currentNode = currentNode->Next;
    }

    return i;
}

void LinkConnect(const int& a, const int& b, ListNode** const graph)
{
    InsertListNode(b, FindAscendPos(b, graph[a]), graph[a]);

    InsertListNode(a, FindAscendPos(a, graph[b]), graph[b]);
}

bool IsLinkConnected(int a, int b, ListNode** graph)
{
    if (graph[a] == NULL || graph[b] == NULL)
    {
        return false;
    }
    if (Find(a, graph[b]) == NULL)
    {
        return false;
    }

    return true;
}

void DFS(ListNode** graph, ListNode* graphList, bool* isVisited)
{
    ListNode* currentNode = graphList;
    while (currentNode != NULL)
    {
        // 如果该节点未被访问过
        if (!isVisited[currentNode->Data])
        {
            isVisited[currentNode->Data] = true;
            printf("%d ", currentNode->Data);
            // 节点的邻接点:graph[currentNode->Data]
            DFS(graph, graph[currentNode->Data], isVisited);
        }
        currentNode = currentNode->Next;
    }
}

void BFS(ListNode** graph, ListNode* graphList, bool* isVisited)
{
    queue<ListNode*> t;

    t.push(graph[graphList->Data]);
    isVisited[graphList->Data] = true;

    while (!t.empty())
    {
        ListNode* currentNode = t.front();
        t.pop();

        printf("%d ", currentNode->Data);

        while (currentNode->Next != NULL)
        {
            currentNode = currentNode->Next;
            if (!isVisited[currentNode->Data])
            {
                t.push(graph[currentNode->Data]);
                isVisited[currentNode->Data] = true;
            }
        }
    }
}

void ComponentsSearch(ListNode** graph, bool* isVisited, int N, int function)
{
    for (int i = 0; i < N; i++)
    {
        if (!isVisited[graph[i]->Data])
        {
            if (function == 1)
            {
                printf("{ ");
                DFS(graph, graph[i], isVisited);
                printf("}\n");
            }
            else
            {
                printf("{ ");
                BFS(graph, graph[i], isVisited);
                printf("}\n");
            }
        }
    }
}

int main(void)
{
    int N;
    int E;
    scanf("%d %d", &N, &E);

    ListNode** graph = CreateListGraph(MAXSIZE);

    for (int i = 0; i < E; i++)
    {
        int vertical;
        int horizontal;
        scanf("%d %d", &vertical, &horizontal);

        LinkConnect(vertical, horizontal, graph);
    }

    bool isVisited[12];
    for (int i = 0; i < 12; i++)
    {
        isVisited[i] = false;
    }

    int firstList = 0;
    while (graph[firstList] == NULL)
    {
        firstList++;
    }

    ComponentsSearch(graph, isVisited, N, 1);
    for (int i = 0; i < 12; i++)
    {
        isVisited[i] = false;
    }
    ComponentsSearch(graph, isVisited, N, 2);
    return 0;
}
时间: 2024-08-10 19:00:42

06-图1. List Components (25) (邻接表实现)的相关文章

图论——图的邻接表实现——Java语言(完整demo)

1.图的简单实现方法--邻接矩阵 表示图的一种简单的方法是使用一个一维数组和一个二维数组,称为领接矩阵(adjacent matrix)表示法. 对于每条边(u,v),置A[u,v]等于true:否则,数组的元素就是false.如果边有一个权,那么可以置A[u][v]等于该权,而使用一个很大或者很小的权来标记不存在的边.虽然这样表示非常简单,但是,它的空间需求则为θ(|V|2),如果图的边不是很多,那么这种表示的代价就太大了.若图是稠密(dense)的:|E|=θ(|V|2),则领接矩阵是合适的

数据结构Java版之邻接表实现图(十)

邻接表实现图,实际上是在一个数组里面存放链表,链表存放的是连接当前节点的其他节点. package mygraph; import java.util.ArrayList; import java.util.List; public class Table { private List<List<Character>> list; private List<Character> headNodes; private int n; private int nVerts;

用邻接表实现无向图的创建与输出

1 #include<stdio.h> 2 #include <iostream> 3 #include<algorithm> 4 using namespace std; 5 #define MVNum 100 6 typedef struct ArcNode // 边表结点 7 { 8 int adjvex; // 邻接点域,存储该顶点对应的下标 9 //int info; //用于存储权值,对于非网图可以不需要 10 struct ArcNode *nextarc

JAVA邻接表实现拓扑排序

由于一直不适用邻接表 ,现在先贴一段使用邻接矩阵实现图的拓扑排序以及判断有无回路的问题.自己做的图.将就看吧. package TopSort; import java.util.LinkedList; import java.util.Scanner; /*拓扑序列:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性 * 序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前. * */ p

用邻接表实现某个点入度和出度

#include <cstdio> #include <cstring> #include <cctype> using namespace std; typedef struct node{//邻接表上的节点 int n; struct node * next; } GNode; typedef struct graph{//图的整个结构 int cn;//顶点个数 int bn;//边的个数 GNode *list;//顶点的数组相当于list[]; }Graph;

05-图1. List Components (25)

05-图1. List Components (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue For a given undirected graph with N vertices and E edges, please list all the connected components by both DFS and BFS. Assume that all the vertices are nu

图基本算法 图的表示方法 邻接矩阵 邻接表

要表示一个图G=(V,E),有两种标准的表示方法,即邻接表和邻接矩阵.这两种表示法既可用于有向图,也可用于无向图.通常采用邻接表表示法,因为用这种方法表示稀疏图(图中边数远小于点个数)比较紧凑.但当遇到稠密图(|E|接近于|V|^2)或必须很快判别两个给定顶点手否存在连接边时,通常采用邻接矩阵表示法,例如求最短路径算法中,就采用邻接矩阵表示. 图G=<V,E>的邻接表表示是由一个包含|V|个列表的数组Adj所组成,其中每个列表对应于V中的一个顶点.对于每一个u∈V,邻接表Adj[u]包含所有满

用顺序表实现一个循环队列

队列是一种先进先出的线性表,简称FIFO.允许插入的一端为队尾,允许出列的一端为队头. 比如一个队列q=(p1,p2,p3,p4...pn),p1就是那个队头,pn就是队尾.出列时总是从p1开始 向后,入列时总是从pn后面插入.就像敲键盘,依次敲qwr,屏幕上显示的就是qwr,先敲的先显 示. 以下代码是用顺序表实现一个循环队列 1 /** 2 * @filename queue.c 3 * @author haohaibo 4 * @data 2017/4/12 5 * @brief 用顺序表

SQL SERVER 2014--内存表实现秒杀场景

===================================== 网上针对“秒杀”的解决方案很多,数据拆分化解热点,READPASH解决锁问题,应用程序排队限制并发等等很多方式,各有优缺点,只为证明一句名言:条条大路通罗马. ===================================== 今天拿SQL SERVER 2014的内存表来试水“秒杀”,内存表使用“版本”解决了高并发下锁请求和阻塞的问题,使用HASH索引来处理数据页“热点”的问题,解决了PAGE_LATCH等待,

DropDownList绑定数据表实现两级联动示例

这篇文章主要介绍了DropDownList绑定数据表实现两级联动具体实现,需要的朋友可以参考下 场景一:平时我们在DropDownList控件下添加下拉选项时,都会使用它的Item.Add方法,直接在代码下添加.如果我们想添加或修改下拉选项,则必须去修改源代码.如果几个DropDownList控件的下拉选项相同,我们则需要重复添加好多次,后期的维护工作很不方便. 场景二:我们在12306网站买票时,肯定遇到过这么一种情景:我们需要先选定目的地的省份,选完省份后在城市选框中会自动加载该省份的城市,