数据结构封装之《StaticList静态链表》

说明:

  1. 该静态链表实则是SeqList顺序表的改版,因其每一个元素都有一个指向下一个元素的下标编号,通过更改2个下标的数值就可以替代传统数组进行插入操作时需要移动数组每一个元素的行为,其插入数值的操作将变得更高效。(有大量的插入操作时,该数据结构适合使用)

  2. 插入的数据,都是将目标数据的地址存入数组下一个空的位置。其顺序是通过TStaticListNode.next下标来确定的;

  3. TStaticList使用了变长结构体的方法,如下:
    Struct Packet
    {
     int state;
     int len;
     char cData[0]; //这里的0长数组就为变长结构体提供了非常好的支持
    };
    首先对0长数组做一个解释:
    用途 :长度为0的数组的主要用途是为了满足需要变长度的结构体。
    用法 :在一个结构体的最后 ,申明一个长度为0的数组,就可以使得这个结构体是可变长的。对于编译器来说,此时长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量

  4. 容量限定,可以存储任何数据类型,无格式要求。且其具备高效率的插入操作;

下面将给出该数据结构的代码,每个函数的结构分析 ,以及个别主要函数的汇编分析


代码:

StaticList.h

#ifndef _STATICLIST_H_
#define _STATICLIST_H_

typedef void StaticList;
typedef void StaticListNode;

StaticList* StaticList_Create(int capacity);

void StaticList_Destroy(StaticList* list);

void StaticList_Clear(StaticList* list);

int StaticList_Length(StaticList* list);

int StaticList_Capacity(StaticList* list);

int StaticList_Insert(StaticList* list, StaticListNode* node, int pos);

StaticListNode* StaticList_Get(StaticList* list, int pos);

StaticListNode* StaticList_Delete(StaticList* list, int pos);

#endif // _STATICLIST_H_

StaticList.c

#include<stdio.h>
#include<malloc.h>
#include "StaticList.h"

#define AVAILABLE -1

typedef struct _tag_StaticListNode
{
    unsigned int data;
    int next;
} TStaticListNode;

//该结构体的第3个成员是不占内存的,实际占用内存仅有capacity和header;
typedef struct _tag_StaticList
{
    int capacity;
    TStaticListNode header;
    TStaticListNode node[];
} TStaticList;

StaticList* StaticList_Create(int capacity)
{
    TStaticList* ret = NULL;
    int i = 0;

    if (capacity >= 0)
    {
        ret = (TStaticList*)malloc(sizeof(TStaticList) + sizeof(TStaticListNode)*(capacity + 1));
    }

    if (ret != NULL)
    {
        ret->capacity = capacity;
        ret->header.data = 0;
        ret->header.next = 0;

        for (i; i <= capacity; i++)
        {
            ret->node[i].next = AVAILABLE;
        }
    }

    return ret;
}

void StaticList_Destroy(StaticList* list)
{
    free(list);
}

void StaticList_Clear(StaticList* list)
{
    TStaticList* sList = (TStaticList*)list;
    int i = 0;

    if (sList != NULL)
    {
        sList->header.data = 0;
        sList->header.next = 0;

        for (int i = 1; i <= sList->capacity; i++)
        {
            sList->node[i].next = AVAILABLE;
        }
    }
}

int StaticList_Length(StaticList* list)
{
    TStaticList* sList = (TStaticList*)list;
    int ret = -1;

    if (sList != NULL)
    {
        ret = sList->header.data;
    }

    return ret;
}

int StaticList_Capacity(StaticList* list)
{
    TStaticList* sList = (TStaticList*)list;
    int ret = -1;

    if (sList != NULL)
    {
        ret = sList->capacity;
    }

    return ret;
}

int StaticList_Insert(StaticList* list, StaticListNode* node, int pos)
{
    TStaticList* sList = (TStaticList*)list;
    int ret = (sList != NULL);
    int current = 0;
    int index = 0;
    int i = 0;

    ret = ret && (sList->header.data + 1 <= sList->capacity);
    ret = ret && (pos >= 0 && (node != NULL));

    if (ret)
    {
        for (i = 1; i <= sList->capacity; i++)
        {
            if (sList->node[i].next == AVAILABLE)
            {
                index = i;
                break;
            }
        }

        sList->node[index].data = (unsigned int)node;

        sList->node[0] = sList->header;

        for (i = 0; (i < pos) && (sList->node[current].next != 0); i++)
        {
            current = sList->node[current].next;
        }

        sList->node[index].next = sList->node[current].next;
        sList->node[current].next = index;
        sList->node[0].data++;

        sList->header = sList->node[0];
    }

    return ret;
}

StaticListNode* StaticList_Get(StaticList* list, int pos)
{
    TStaticList* sList = (TStaticList*)list;
    StaticListNode* ret = NULL;
    int current = 0;
    int object = 0;
    int i = 0;

    if ((sList != NULL) && (0 <= pos) && (pos < sList->header.data))
    {
        sList->node[0] = sList->header;

        for (i = 0; i < pos; i++)
        {
            current = sList->node[current].next;
        }

        object = sList->node[current].next;

        ret = (StaticList*)(sList->node[object].data);
    }

    return ret;
}

StaticListNode* StaticList_Delete(StaticList* list, int pos)
{
    TStaticList* sList = (TStaticList*)list;
    StaticListNode* ret = NULL;
    int current = 0;
    int object = 0;
    int i = 0;

    if ((sList != NULL) && (pos < sList->header.data))
    {
        sList->node[0] = sList->header;

        for (i = 0; i < pos; i++)
        {
            current = sList->node[current].next;
        }

        object = sList->node[current].next;

        sList->node[current].next = sList->node[object].next;

        sList->node[0].data--;

        sList->header = sList->node[0];

        sList->node[object].next = AVAILABLE;

        ret = (StaticListNode*)(sList->node[object].data);
    }

    return ret;
}

smain.c

#include <stdio.h>
#include <stdlib.h>
#include "StaticList.h"


int main(int argc, char* argv[]) 
{
    StaticList* list = StaticList_Create(10);

    int index = 0;

    int i = 77;
    int j = 88;
    int k = 99;
    int x = 3;
    int y = 4;
    int z = 5;

    StaticList_Insert(list, &i, 0);
    StaticList_Insert(list, &j, 0);
    StaticList_Insert(list, &k, 0);
    StaticList_Insert(list, &x, 0);
    StaticList_Insert(list, &y, 0);
    StaticList_Insert(list, &z, 3);

    for (index = 0; index < StaticList_Length(list); index++)
    {
        int* p = (int*)StaticList_Get(list, index);

        printf("%d\n", *p);
    }

    printf("\n");

    while (StaticList_Length(list)>0)
    {
        int* p = (int *)StaticList_Delete(list, 0);

        printf("%d\n", *p);
    }

    return 0;
}

函数结构分析:

1.StaticList_Create

2.StaticList_Destroy

3.StaticList_Clear

4.StaticList_Length

5.StaticList_Capacity

6.StaticList_Insert

7.StaticList_Get

8.StaticList_Delete


汇编分析:

1.StaticList_Create

2.StaticList_Insert

3.StaticList_Delete

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值