数据结构---邻接表

  • 参考书籍:<<大话数据结构>>--邻接表
  • 简单的说:用一个结构体存链表头,链表头连接一个链表。 有几条链表,就用几个数组。
  • 下面的代码:
  1. chainTableHead中firstson存链表头,sonCount记录链表头对应的链表大小,a表示这个链表头的标识
  2. chainTableNode则是一个链表

  3. main中是简单的插入,删除的示例demo

  • 应用场景:多个root证书,生成了多个CA证书,CA证书生成了多个用户使用的证书A。关系大概是:root-->CA1-->CA2-->A (其中CA1, CA2都算CA证书)。 需要把证书之间的关系理出来,并且把root证书对应证书链找到。其中chainTableHead存证书链的名字(int a) , firstson指向第一个root证书。链表存了root-->CA1-->CA2-->A
  • 代码
//数组 + 单链表
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <stdbool.h>

#define DataType int
//单向链表
typedef struct chainTableNode
{
    DataType data;
    struct chainTableNode* next;
}chainTableNode;
 

static chainTableNode *headNode = NULL, *tailNode = NULL;
static int chainTableNodeCount = 0;


//链表在last和next之间插入一个节点
chainTableNode* insertListNode(chainTableNode* last, chainTableNode* next)
{
    // generate a node
    chainTableNode* newNode = (chainTableNode*) malloc(sizeof(chainTableNode));
    // new node be pointed by last node
    if (last != NULL) {last->next = newNode;}
    // new node point to next node 
    newNode->next = next;

    chainTableNodeCount++;
    return newNode;
}
 
//链表删除数据
void del_ListNode(chainTableNode* node)
{
    if (node == headNode) {
        chainTableNode* tmp = headNode->next;
        free(headNode);
        headNode = tmp;

        if(--chainTableNodeCount == 0)
        {
            headNode = NULL;
            tailNode = NULL;
        }
        return;
    }

    chainTableNode* next;
    chainTableNode* last = NULL, *nodeTmp=NULL;
    {
        // get next node
        next = node->next;

        // get last node
        for (nodeTmp = headNode; nodeTmp != NULL; (nodeTmp = nodeTmp->next))
        {
            if (nodeTmp->next == node) 
                last = nodeTmp;
        }
    
        // link last node to next node
        if (last)
            last->next = next;
    }
    // update tailnode val
    if (node == tailNode) {
        tailNode = last;
    }
    free(node);
    chainTableNodeCount--;
    return;
}

//链表打印数据
void printfData(DataType* data) {

    printf("val [%d]\n", *data);
}

// print all list val
void printfListVal()
{
    chainTableNode* node;
    int a = 0;
    printf("===============chaintable head %p count %d\n", headNode, chainTableNodeCount);

    for (node = headNode; node != NULL; (node = node->next))
    {
        printf("node %p-->%p--\n", node, node->next);
    }
    for (node = headNode; node != NULL; (node = node->next))
    {
        printf("node = [%p] ", node);
        printfData(&node->data);
    }
    printf("===============chaintable tail %p\n", tailNode);
}

//链表尾插法
chainTableNode* create_NodeatTail(DataType data)
{
    chainTableNode* tmp = NULL;
    if (!headNode) {
        headNode = insertListNode(NULL, NULL);
        tailNode = headNode;
        tmp = headNode;
    } else {
        tmp = insertListNode(tailNode, NULL);
        tailNode = tmp;
    }
    memcpy(&tmp->data, &data, sizeof(DataType));
    return tmp;
}

//链表:在last和next之间插入节点并赋值
void create_NodeafterNode(DataType* data, chainTableNode* last, chainTableNode* next)
{
    chainTableNode* tmp = insertListNode(last, next);
    memcpy(&tmp->data, data, sizeof(DataType));
}





//邻接表



// chainTableHead作为指向链表头的节点
typedef struct chainTableHead
{
    int a;
    int sonCount;   // 链表个数
    chainTableNode* firstson; // 第一个链表
} chainTableHead;

#define MAX_HEAD_NUM 10
static chainTableHead* headNodeArray[MAX_HEAD_NUM] = {NULL};


void printfNodeVal()
{
    char data[512] = {'\0'};
    for (int i = 0; i < MAX_HEAD_NUM; i++)
    {
        if (headNodeArray[i]) {
            snprintf(data, 512, "head pos [%d] val[%d]", i, headNodeArray[i]->a);
            printf("%s",data);
            if (headNodeArray[i]->firstson) {
                snprintf(data, 512," firstson[%p]", headNodeArray[i]->firstson);
                printf("%s",data);
            }
            printf("\n");

            headNode = headNodeArray[i]->firstson;
            chainTableNodeCount = headNodeArray[i]->sonCount;
            printfListVal();
            printf("\n");

            headNode = NULL;
        }
    }
}

bool create_ChildTailNode(int pos, chainTableNode* son)
{
    int ret = false;
    static int firstFlag[MAX_HEAD_NUM] = {1,1,1,1,1,1,1,1,1,1};
// prepare data headnode and count
    headNode = headNodeArray[pos]->firstson;
    chainTableNodeCount = headNodeArray[pos]->sonCount;
// cretate node
    chainTableNode* tmp = NULL;
    if (son) {
       tmp = create_NodeatTail(son->data);
       ret = true;
    } else {
        ret = false;
    }
// update head firstnode
    if (firstFlag[pos]) {
        headNodeArray[pos]->firstson = tmp;
        firstFlag[pos] = 0;
    }
// update head soncount
    headNodeArray[pos]->sonCount = chainTableNodeCount;
    headNode = NULL;
    return ret;
}

// 删除第pos个链表的数据
bool del_ChildNode(int pos, DataType data)
{
    chainTableNode* tmp = NULL;
    // find data in chainTablep[pos]
    if (headNodeArray[pos]) {
        for (tmp = headNodeArray[pos]->firstson; tmp != NULL; tmp = tmp->next) {
            if (tmp->data == data) {
                break;
            }
        }
    }
    if (tmp) {
        headNode = headNodeArray[pos]->firstson;
        chainTableNodeCount = headNodeArray[pos]->sonCount;
        del_ListNode(tmp);
        headNodeArray[pos]->firstson = headNode;
        headNodeArray[pos]->sonCount = chainTableNodeCount;
    } else {
        printf("didn't find [%d] in chainTable\n", data);
    }
}
void create_TreeHeadNode(int pos, int value, chainTableNode* son)
{
    if (pos > MAX_HEAD_NUM || pos < 0) {
        printf("over MAX_HEAD_NUM \n ");
        return;
    }
    if (!headNodeArray[pos]) {
// create first chainTableHead
        headNodeArray[pos] = (chainTableHead*)malloc(sizeof(chainTableHead));
        headNodeArray[pos]->a = value;
// create childnode with son
        chainTableNodeCount = 0;
        if (son && create_ChildTailNode(pos, son)) {
            headNodeArray[pos]->sonCount = chainTableNodeCount;
        } else {
            printf("create tailnode null or error \n ");
        }
    } else {
        printf("del headnode first \n ");
    }
}


int main()
{
    {
        // chainTableNode son = {
        //     .data = 20,
        //     .next = NULL,
        // };
        // create_TreeHeadNode(0, 2, &son);
        // chainTableNode son22 = {
        //     .data = 32,
        //     .next = NULL,
        // };
        // create_ChildTailNode(0, &son22);

        // create_TreeHeadNode(1, 4, NULL);
        // chainTableNode son33 = {
        //     .data = 32,
        //     .next = NULL,
        // };
        // create_ChildTailNode(1, &son33);
        // printfNodeVal();
    }

    {
        chainTableNode son = {
            .data = 20,
            .next = NULL,
        };
        create_TreeHeadNode(0, 2, &son);

        chainTableNode son22 = {
            .data = 32,
            .next = NULL,
        };
        create_ChildTailNode(0, &son22);
        printfNodeVal();

        del_ChildNode(0, 20);
        printfNodeVal();

        del_ChildNode(0, 32);
        printfNodeVal();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值