【C语言数据结构】静态单链表

StaticLinkLinst.h

#ifndef STATIC_LINKLIST_H
#define STATIC_LINKLIST_H

typedef void StaticLinkListNode;    //静态单链表节点
typedef void StaticLinkList;        //静态单链表

/*
 * 创建静态单链表
 * @param capacity 静态单链表的最大容量
 * @return 返回静态单链表的指针
 */
StaticLinkList* StaticLinkList_Create(int capacity);

/*
 * 销毁静态单链表
 * @param list 静态单链表的指针
 */
void StaticLinkList_Destroy(StaticLinkList *list);

/*
 * 清空静态单链表
 * @param list 静态单链表的指针
 */
void StaticLinkList_Clear(StaticLinkList *list);

/*
 * 向静态单链表pos位置处插入元素
 * @param list 静态单链表指针
 * @param node 元素指针
 * @param pos 插入的索引
 */
int StaticLinkList_Insert(StaticLinkList *list,StaticLinkListNode *node,int pos);

/*
 * 获取静态单链表中索引位置处的元素
 * @param list   静态单链表指针
 * @param pos   静态单链表索引值
 * @param return 元素指针
 */
StaticLinkListNode* StaticLinkList_Get(StaticLinkList *list,int pos);

/*
 * 删除静态单链表中索引位置处的值
 * @param list 静态单链表的指针
 * @param pos   静态单链表索引
 * @param return 非0表示删除成功
 */
int StaticLinkList_Remove(StaticLinkList *list,int pos);

/*
 * 获取静态单链表当前已存储元素的个数
 * @param list 静态单链表的指针
 * @return 静态单链表中已存储元素的个数
 */
int StaticLinkList_Length(StaticLinkList *list);

/*
 * 获取静态单链表最大可存储元素的个数
 * @param list 静态单链表的指针
 * @return 静态单链表最大可存储元素的个数
 */
int StaticLinkList_Capacity(StaticLinkList *list);

#endif // STATICLINKLIST_H

StaticLinkList.c

#include "StaticLinkList.h"
#include "malloc.h"

#define NO_NODE  -1

typedef struct _StaticLinkListNode
{
    unsigned int data;  //数据域指针
    int next;           //下一个节点的数组下标
}TStaticLinkListNode;

typedef struct _StaticLinkList
{
    int length;
    int capacity;
    TStaticLinkListNode node[]; //用于存储静态链表的柔性数组
}TStaticLinkList;

/*
 * 创建静态单链表
 * @param capacity 静态单链表的最大容量
 * @return 返回静态单链表的指针
 */
StaticLinkList* StaticLinkList_Create(int capacity)
{
    //由于柔性数组的0位置会被作为头节点,所以实际上容量是capapcity + 1
    size_t size = sizeof(TStaticLinkList) + sizeof(TStaticLinkListNode) * (capacity + 1);
    TStaticLinkList *list = (TStaticLinkList *)malloc(size);

    if(list != 0)
    {
        int i;
        list->capacity = capacity;
        list->length = 0;
        list->node[0].next = 0;

        for(i = 1;i <= capacity;i++)
        {
            list->node[i].next = NO_NODE;
        }
    }

    return list;
}

/*
 * 销毁静态单链表
 * @param list 静态单链表的指针
 */
void StaticLinkList_Destroy(StaticLinkList *list)
{
    free(list);
}

/*
 * 清空静态单链表
 * @param list 静态单链表的指针
 */
void StaticLinkList_Clear(StaticLinkList *list)
{
    if(list != 0)
    {
        TStaticLinkList *s_list = (TStaticLinkList *)list;
        s_list->length = 0;
    }
}

/*
 * 向静态单链表pos位置处插入元素
 * @param list 静态单链表指针
 * @param node 元素指针
 * @param pos 插入的索引
 * @param return 非0表示插入成功
 */
int StaticLinkList_Insert(StaticLinkList *list,StaticLinkListNode *node,int pos)
{
    TStaticLinkList *s_list = (TStaticLinkList *)list;
    //判断链表和节点指针不为空,位置合法,增加后容量不会大于最大容量
    int ret = ( (s_list != 0) && (node != 0) && (pos >= 0) &&                 (pos <= s_list->length) && (s_list->length + 1 <= s_list->capacity + 1) );

    if(ret)
    {
        int index = -1;                    //待放入元素的数组下标
        int current = 0;                   //当前节点的数组下标
        int i = 0;
        //遍历查找数组中的空余项
        for(i =1; i <= s_list->capacity;i++)
        {
            if(s_list->node[i].next == NO_NODE)
            {
                index = i;
                break;
            }
        }

        //移动到需要插入位置的前驱
        for(i = 0; i < pos ; i++)
        {
            current = s_list->node[current].next;
        }

        s_list->node[index].next = s_list->node[current].next;
        s_list->node[index].data = (unsigned int)node;
        s_list->node[current].next = index;
        s_list->length++;

    }

    return ret;
}

/*
 * 获取静态单链表中索引位置处的元素
 * @param list   静态单链表指针
 * @param pos   静态单链表索引值
 * @param return 元素指针
 */
StaticLinkListNode* StaticLinkList_Get(StaticLinkList *list,int pos)
{
    TStaticLinkListNode *s_node = 0;
    TStaticLinkList *s_list = (TStaticLinkList *)list;

    if( (list != 0) && (pos >=0) && (pos < s_list->length))
    {
        int current = 0;
        int index = -1;
        int i;
        //移动到需要查询的位置
        for(i = 0; i < pos ; i++)
        {
            current = s_list->node[current].next;
        }

        //获取元素的数组下标
        index = s_list->node[current].next;
        //将data中的类型强制转换成StaticLinkListNode *,因为插入时保存的就是节点的指针
        s_node = (StaticLinkListNode *)s_list->node[index].data;
    }

    return s_node;
}

/*
 * 删除静态单链表中索引位置处的值
 * @param list 静态单链表的指针
 * @param pos   静态单链表索引
 * @param return 非0表示删除成功
 */
int StaticLinkList_Remove(StaticLinkList *list,int pos)
{
    TStaticLinkList *s_list = (TStaticLinkList *)list;
    int ret = ( (s_list != 0) && (pos >= 0) && (pos < s_list->length));

    if(ret)
    {
        int index = -1;
        int current = 0;
        int i = 0;

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

        //被删除元素的数组下标
        index = s_list->node[current].next;
        //将被删元素的后继下标赋值给除被删除元素前驱的后继下标
        s_list->node[current].next = s_list->node[index].next;
        //设置被删除元素的后继下标为NO_NODE
        s_list->node[index].next = NO_NODE;
        s_list->length--;

    }

    return ret;
}

/*
 * 获取静态单链表当前已存储元素的个数
 * @param list 静态单链表的指针
 * @return 静态单链表中已存储元素的个数
 */
int StaticLinkList_Length(StaticLinkList *list)
{
    int ret = -1;
    if(list != 0)
    {
        TStaticLinkList *s_list = (TStaticLinkList *)list;
        ret = s_list->length;
    }

    return ret;
}

/*
 * 获取静态单链表最大可存储元素的个数
 * @param list 静态单链表的指针
 * @return 静态单链表最大可存储元素的个数
 */
int StaticLinkList_Capacity(StaticLinkList *list)
{
    int ret = -1;

    if(list != 0)
    {
        TStaticLinkList *s_list = (TStaticLinkList *)list;
        ret = s_list->capacity;
    }

    return ret;
}

测试代码

#include <stdio.h>
#include "StaticLinkList.h"

int main(void)
{
    int i,*j;
    int a[5];
    StaticLinkList *list = StaticLinkList_Create(5);

   for(i = 0;i < 5;i++)
   {
       a[i] = i;
   }

   for(i = 0; i < 5;i++)
   {
        StaticLinkList_Insert(list,&(a[i]),0);
   }

   StaticLinkList_Remove(list,0);

   for(i = 0; i < StaticLinkList_Length(list);i++)
   {
      j = StaticLinkList_Get(list,i);
      printf("%d\n",*j);
   }

   return 0;
}
时间: 2024-10-13 19:01:40

【C语言数据结构】静态单链表的相关文章

C语言数据结构之单链表

链表由多个节点构成,节点之间可以灵活的插入.删除.链表以结构体的自引用原理,可以在内存中以不连续的方式动态分配内存来存储数据,这样的结构体就是链表的一个节点. 一个节点分为两个域:一个是数据域,一个是指针域,这方便链表在存储数据的同时可以方便地找到下一个节点. 相比于数组:数组定义相对简单些,是以连续的内存存储数据,在定义时就确定了长度,这样相比于链表的动态存储,数组就存在有可能数据不够长或内存浪费的缺点. 对于单链表,在此从建立链表开始,实现链表的增添.删除和输出链表内容.由于链表是动态存储,

【C语言数据结构】单链表

LinkList.h #ifndef LINK_LIST_H #define LINK_LIST_H //链表节点 typedef struct _LinkListNode {     struct _LinkListNode *next; }LinkListNode; //单链表 typedef void LinkList; /*  * 创建单链表  * @return 返回单链表的指针  */ LinkList* LinkList_Create(); /*  * 销毁单链表  * @para

【数据结构】单链表&amp;&amp;静态链表详解和代码实例

喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 01 单链表(Singly Linked List ) 1.1 什么是单链表? 单链表是一种链式存储的结构.它动态的为节点分配存储单元.当有节点插入时,系统动态的为结点分配空间.在结点删除时,应该及时释放相应的存储单元,以防止内存泄露.由于是链式存储,所以操作单链表时,必须知道头结点或者头指针的位置.并且,在查找第i个节点时,必须找到第i-1个节点. 1.2 单链表的存储结构代码描述 对于链式存储,通过上一节的讲解相信大家已

静态单链表

最近在学习数据结构的单链表部分,于是写了一个静态单链表做练习.实现了对其初始化.添加.更改.删除等功能的实现. "Seqlist.h" #pragma once #define __SEQ_LIST__ #ifdef __SEQ_LIST__ #include <stdio.h> #include <assert.h> #include <string.h> #define MAXSIZE 100 typedef int DataType; type

第二十五课 静态单链表的实现

静态单链表是一种新的数据结构类型. 我们往线性表中添加的元素的个数是固定的,例如最大100个. 只是这100个元素会经常的变动. 这时候是顺序表还是单链表合适呢? 显然是单链表,但是单链表也有问题. 缺陷: 解决方案: 我们在顺序表的内部预留了空间,这片空间用来增加删除数据元素.配合单链表就形成了静态单链表. 在静态单链表中的操作和普通单链表几乎一样,只有两个函数有差异:create和destroy 静态单链表的继承层次结构: 原文地址:https://www.cnblogs.com/wanme

线性表的链式存储——静态单链表的实现

1,单链表的一个缺陷: 1,触发条件: 1,长时间使用单链表对象频繁增加和删除数据元素: 2,可能的结果: 1,堆空间产生大量的内存碎片,导致系统运行缓慢: 1,增加一个节点,就会在堆空间创建一个结点,但是频繁创建删除就会有大量碎片: 2,解决方案,设计新的线性表: 1,设计思路: 1,在“单链表”的内部增加一片预留的空间,所有的 Node 对象都在这片空间中动态创建和动态销毁: 2,顺序表 + 单链表 = 静态单链表: 3,除了内存分配的不同外,静态单链表和单链表在其他操作上完全一样,只用改写

C#数据结构-单链表

理论基础: 链表是用一组任意的存储单元来存储线性表中的数据元素. 如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List). 单链表由头引用H唯一确定.头引用指向单链表的第一个结点,也就是把单链表第一个结点的地址放在H中. C#实现: 1接口 引用线性表的接口IListDS<T> 2实现 首先,必须定义一个单链表的节点类.  1 public class Node<T> 2    { 3        private T data

静态单链表和动态单链表的区别

链表中结点的分配和回收是由系统提供的标准函数malloc和free动态实现的,称之为动态链表. 如果程序支持指针,则可按照我们的一般形式实现链表, 需要时分配,不需要时回收即可. 动态链表的空间是可以动态扩展的. typedef struct  node{ EleType data; struct node * pNext; }Node; 有些高级语言中没有"指针"数据类型,只能用数组来模拟线性链表的结构, 数组元素中的指针"域"存放的不是元素在内存中的真实地址,而

数据结构之---c语言实现循环单链表操作

//=========杨鑫========================// //循环单链表的实现 #include <stdio.h> #include <stdlib.h> typedef int ElemType; //定义结点类型 typedef struct Node { ElemType data; struct Node *next; }Node,*LinkedList; int count = 0; //1.单循环链表的初始化 LinkedList init_ci