数据结构与算法基础之线性表链式实现(C语言)

数据结构与算法基础之线性表链式实现

学习来源:
数据结构与算法基础(青岛大学-王卓)

地址:

https://www.bilibili.com/video/BV1nJ411V7bd?p=22&spm_id_from=pageDriver

背景:
实现视频里老师的伪代码,并不完全一样,但基本雷同。

更新
2021/5/25
增加linklist函数,用于何必两个顺序表
2021/6/19
修改所有代码,可以兼容所有数据类型。


代码:

ChainDynamic.h

#ifndef _CHAINDYNAMIC_H_
#define _CHAINDYNAMIC_H_

typedef struct ChainDynamic *ChainDynamic;//Chain list object
typedef void (*ChainOwnShow)(void *);


//Create the chain list
//The "DataSize" is the data type size of each chain element.
ChainDynamic Create_ChainDynamic(unsigned DataSize);

//Add a element with "Data" to the chain list "cd" on list tail.
void AddTail_ChainDynamic(ChainDynamic cd, void *Data);

//Get the "index" data from chain list "cd" and store it into "Data".
void Get_ChainDynamic(ChainDynamic cd, unsigned index, void *Data);

//Show chain list "cd" element's data on console.
//The "show" is your function about how to show your list's data.
void Show_ChainDynamic(ChainDynamic cd, ChainOwnShow show);

//Add an element with "Data" to the chain list "cd" on list head.
void AddHead_ChainDynamic(ChainDynamic cd, void *Data);

//Delete an element of chain list "cd" on list head.
void DeleteHead_ChainDynamic(ChainDynamic cd);

//Delete an element of chain list "cd" on list tail.
void DeleteTail_ChainDynamic(ChainDynamic cd);

//Empty the chain list "cd".
void Clear_ChainDynamic(ChainDynamic cd);

//Destroy chain list "cd".
void Destroy_ChainDynamic(ChainDynamic *pcd);

//Insert a node which data is "Data" into chain list "cd" before "index" node.
void Insert_ChainDynamic(ChainDynamic cd, unsigned index, void *Data);

//Remove the "index" node of chain list "cd".
void Remove_ChainDynamic(ChainDynamic cd, unsigned index);

//Change the value of node in the chain.
void Change_ChainDynamic(ChainDynamic cd, unsigned index, void *Data);

//Judge if chain list "cd" is empty.
int IsEmpty_ChainDynamic(ChainDynamic cd);


#endif


ChainDynamic.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ChainDynamic.h"
#include "CommonFunc.h"

struct Node
{
    void *Data;//Data pointer
    struct Node *NextNode;//Next node address
};
typedef struct Node Node;

struct ChainDynamic
{
    Node *head;//List head node.
    unsigned DataSize;//List each data's type size.
};


static Node * GetNode_ChainDynamic(ChainDynamic cd, unsigned index);
static unsigned GetLength_ChainDynamic(ChainDynamic cd);

void Destroy_ChainDynamic(ChainDynamic *pcd)
{
    NULLPointOut(pcd, "Destroy_ChainDynamic", "pcd");
    NULLPointOut(*pcd, "Destroy_ChainDynamic", "cd");
    NULLPointOut((*pcd)->head, "Destroy_ChainDynamic", "head");

    Clear_ChainDynamic(*pcd);
    free((*pcd)->head);
    free(*pcd);
    *pcd = NULL;

    return;
}

void Clear_ChainDynamic(ChainDynamic cd)
{
    NULLPointOut(cd, "Clear_ChainDynamic", "cd");

    while(!IsEmpty_ChainDynamic(cd))
    {
        DeleteHead_ChainDynamic(cd);
    }
    
    return;
}

void DeleteHead_ChainDynamic(ChainDynamic cd)
{
    NULLPointOut(cd, "DeleteHead_ChainDynamic", "cd");

    Remove_ChainDynamic(cd, 1);

    return;
}

void DeleteTail_ChainDynamic(ChainDynamic cd)
{
    NULLPointOut(cd, "DeleteTail_ChainDynamic", "cd");

    Remove_ChainDynamic(cd, GetLength_ChainDynamic(cd));

    return;
}

void AddHead_ChainDynamic(ChainDynamic cd, void *Data)
{
    NULLPointOut(cd, "AddHead_ChainDynamic", "cd");
    NULLPointOut(Data, "AddHead_ChainDynamic", "Data");

    Insert_ChainDynamic(cd, 1, Data);

    return;
}

void AddTail_ChainDynamic(ChainDynamic cd, void *Data)
{
    NULLPointOut(cd, "AddTail_ChainDynamic", "cd");
    NULLPointOut(Data, "AddTail_ChainDynamic", "Data");

    Insert_ChainDynamic(cd, GetLength_ChainDynamic(cd) + 1, Data);

    return;
}

void Change_ChainDynamic(ChainDynamic cd, unsigned index, void *Data)
{
    NULLPointOut(cd, "Change_ChainDynamic", "cd");
    NULLPointOut(Data, "Change_ChainDynamic", "Data");
    if(index > GetLength_ChainDynamic(cd) || index == 0)
    {
        puts("Change_ChainDynamic ERROR: index overstep list's boundary.");
        exit(-1);
    }

    Node *n = GetNode_ChainDynamic(cd, index);
    memcpy(n->Data, Data, cd->DataSize);

    return;
}

void Remove_ChainDynamic(ChainDynamic cd, unsigned index)
{
    NULLPointOut(cd, "Remove_ChainDynamic", "cd");
    if(index > GetLength_ChainDynamic(cd) || index == 0)
    {
        puts("Remove_ChainDynamic ERROR: index overstep list's boundary.");
        exit(-1);
    }
    
    Node *before = GetNode_ChainDynamic(cd, index - 1);
    Node *n = GetNode_ChainDynamic(cd, index);

    before->NextNode = n->NextNode;

    free(n->Data);
    free(n);

    return;
}

void Get_ChainDynamic(ChainDynamic cd, unsigned index, void *Data)
{
    NULLPointOut(cd, "Get_ChainDynamic", "cd");
    NULLPointOut(Data, "Get_ChainDynamic", "Data");
    
    if(index > GetLength_ChainDynamic(cd) || index == 0)
    {
        puts("Get_ChainDynamic ERROR: index overstep list's boundary.");
        exit(-1);
    }

    Node *n = GetNode_ChainDynamic(cd, index);
    memcpy(Data, n->Data, cd->DataSize);
    
    return;
}

void Show_ChainDynamic(ChainDynamic cd, ChainOwnShow show)
{
    NULLPointOut(cd, "Show_ChainDynamic", "cd");

    puts("-------------");
    printf("length=%u, DataSize=%u\n", GetLength_ChainDynamic(cd), cd->DataSize);

    Node *n = cd->head;
    while(n->NextNode != NULL)
    {
        n = n->NextNode;
        show(n->Data);
    }
    puts("");
    puts("");

    return;
}

//Get the "index" node from chain list "cd".
static Node * GetNode_ChainDynamic(ChainDynamic cd, unsigned index)
{
    NULLPointOut(cd, "GetNode_ChainDynamic", "cd");

    if(index > GetLength_ChainDynamic(cd))
    {
        puts("GetNode_ChainDynamic ERROR: index overstep list's boundary");
        exit(-1);
    }

    unsigned i;
    Node *n = cd->head;
    for(i = 0; i < index; i++)
    {
        n = n->NextNode;
    }

    return n;
}


int IsEmpty_ChainDynamic(ChainDynamic cd)
{
    NULLPointOut(cd, "IsEmpty_ChainDynamic", "cd");

    return GetLength_ChainDynamic(cd) == 0 ? 1 : 0;
}

//Get chain list "cd" length now.
static unsigned GetLength_ChainDynamic(ChainDynamic cd)
{
    NULLPointOut(cd, "GetLength_ChainDynamic", "cd");

    Node *n = cd->head;
    unsigned i = 0;
    while(n->NextNode != NULL)
    {
        i++;
        n = n->NextNode;
    }

    return i;
}

ChainDynamic Create_ChainDynamic(unsigned DataSize)
{
    if(DataSize == 0)
    {
        return NULL;
    }

    ChainDynamic cd = (ChainDynamic)malloc(sizeof(struct ChainDynamic));
    NULLMallocOut(cd, "Create_ChainDynamic", "cd");

    Node *head = (Node *)malloc(sizeof(Node));    
    NULLMallocOut(head, "Create_ChainDynamic", "head");

    head->Data = NULL;
    head->NextNode = NULL;

    cd->head = head;
    cd->DataSize = DataSize;

    return cd;
}

void Insert_ChainDynamic(ChainDynamic cd, unsigned index, void *Data)
{
    NULLPointOut(cd, "Insert_ChainDynamic", "cd");
    NULLPointOut(Data, "Insert_ChainDynamic", "Data");

    if(index > GetLength_ChainDynamic(cd) + 1 || index == 0)
    {
        puts("Insert_ChainDynamic ERROR: index overstep list's boundary.");
        exit(-1);
    }
    
    void *newData = malloc(cd->DataSize);
    NULLMallocOut(newData, "Insert_ChainDynamic", "Data");

    Node *n = (Node *)malloc(sizeof(Node));
    NULLMallocOut(n, "Insert_ChainDynamic", "n");

    memcpy(newData, Data, cd->DataSize);
    n->Data = newData;
    
    Node *before = GetNode_ChainDynamic(cd, index - 1);
    n->NextNode = before->NextNode;
    before->NextNode = n;

    return;    
}

CommonFunc.h

#ifndef _COMMONFUNC_H_
#define _COMMONFUNC_H_


//If p equal null, exit program and pop a err message.
//The parameter 'func' is error function name.
//The paremeter 'element' is problem variables.
void NULLPointOut(void *p, char *func, char *element);
void NULLMallocOut(void *p, char *func, char *element);


#endif

CommonFunc.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void NULLPointOut(void *p, char *func, char *element)
{
    if(func == NULL)
    {
        puts("NULLPointOut ERROR: NULL point exception 'func'");
        exit(-1);
    }
    else if(element == NULL)
    {
        puts("NULLPointOut ERROR: NULL point exception 'element'");
        exit(-1);
    }

    if(p == NULL)
    {
        printf("%s ERROR: NULL point exception '%s'\n", func, element);
        exit(-1);
    }

    return;
}

void NULLMallocOut(void *p, char *func, char *element)
{
    NULLPointOut(func, "NULLMallocOut", "func");
    NULLPointOut(element, "NULLMallocOut", "element");

    if(p == NULL)
    {
        printf("%s ERROR: Malloc error '%s'\n", func, element);
        exit(-1);
    }

    return;
}

example.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CommonFunc.h"
#include "ChainDynamic.h"

void myshow(void *Data)
{
    char *a = (char *)Data;
    printf("%s ", a);

    return;
}

int main(void)
{
    ChainDynamic cd = Create_ChainDynamic(5);

    AddHead_ChainDynamic(cd, "abcd");
    AddHead_ChainDynamic(cd, "qwer");
    AddHead_ChainDynamic(cd, "1234");
    Show_ChainDynamic(cd, myshow);

    Clear_ChainDynamic(cd);
    Show_ChainDynamic(cd, myshow);

    AddHead_ChainDynamic(cd, "abcd");
    AddHead_ChainDynamic(cd, "qwer");
    AddHead_ChainDynamic(cd, "1234");
    Show_ChainDynamic(cd, myshow);
    

    Destroy_ChainDynamic(&cd);

    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值