静态链表实现与分析

静态链表给没有指针的高级语言设计的一种实现单链表能力的方法,
  • 实现方法
    使用一个数组的方式储存每一个元素,每个数据元素都是由两个数据域组成,data 和 cur。
    data表示当前数据域,cur表示当前元素的直接后继所在数组中的位置
    这个数组用来表示两个链表,一个数据链表,一个备用链表,下图用蓝色表示备用链表,绿色为数据链表
    在这里插入图片描述
实现功能说明
  • 初始化

以零号下标元素为备用链表指针
以一号下标元素为头结点下标元素

  • 插入元素

从备用链表中申请一个空间(需要自己实现Mymalloc函数),并且将新的节点插入到数据链表
在这里插入图片描述

  • 删除元素
    将结点从数据链表中删除,并且需要实现free,将删除的链表释放到备用链表
    在这里插入图片描述

ps: 静态链表我在网上并没有找到一个标准的定义,自己结合了前几篇链表和可不定长顺序表的特点以及静态链表的思想自己实现的一个静态链表,里面所有的操作都是参考链表所需要的功能的内容,有任何错误欢迎指出

#pragma once

/*
    用于没有指针的高级编程语言
    应结合顺序表和链表的方法实现
    其基本功能应和顺序表链表相同
*/

#define INITSIZE 10

typedef struct sNode {
    int data;//数据域
    int ptr;//指针域
}sNode,*psNode;

typedef struct sList {
    psNode elem;//保存动态内存的地址,用于存放数据
    int length;//有效数据个数
    int listsize;//总单元个数
}sList,*psList;


//初始化
void InitsList(psList pslist);

//头插法
bool Insert_head(psList pslist, int val);

//尾插
bool Insert_tail(psList pslist, int val);

//查找
int Search(psList pslist, int key);

//删除
bool Delete(psList pslist, int key);

bool IsEmpty(psList pslist);

//获取长度,数据个数
int GetLength(psList pslist);

void Show(psList pslist);

//获得key的前驱
int GetPrio(psList pslist, int key);

//获取key后继
int GetNext(psList pslist, int key);

//清空数据
void Clear(psList pslist);

//销毁
void Destroy(psList pslist);

#include"pch.h"
#include"slist.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>



//初始化
void InitsList(psList ps)
{

    assert(ps != NULL);
    if (ps == NULL)
    {
        return;
    }

    //初始化
    /*
        以零号下标元素为备用链表指针
        以一号下标元素为头结点下标元素
        对链表初始化
        申请十个数据空间 ,可用8个数据结点

          数组地址  0 1  2 3 4 5 6 7 8 9
          数据      ________________________________
        指针域      2 0 3 4 5 6 7 8 9 0
            指针域0为空指针
            数组下标为0 备用链表指针  1号下标为头结点 指向空指针 
            备用链表  0(头结点)  2 3 4 5 6 7 8 9
            数据链表  1(头结点)
    */
    ps->listsize = INITSIZE;

   int i = sizeof(sNode);

    ps->elem = ( sNode * )malloc(sizeof(sNode)*INITSIZE);
    i=sizeof(ps->elem);
    ps->length = 0;
    for (int i = 0; i < ps->listsize; i++)
    {
        ps->elem[ i ].ptr = i + 1;
    }
    


    //初始化备用链表
    ps->elem[ 0 ].ptr = 2;
    ps->elem[ 9 ].ptr = 0;

    //初始化数据链表
    ps->elem[ 1 ].ptr = 0;
    
}


/*
    
    头插法:
        数据节点应从 备用链表 申请一个空间存放数据
        当备用链表没用空间时,应从内存申请空间
*/

static void inc(psList ps)
{
    
    int count = ps->listsize;
    ps->listsize *= 2;

    psNode newPtr;

    newPtr = ( sNode * )realloc(ps->elem,sizeof(sNode)*ps->listsize);

    //当前申请空间必须存在
    assert(newPtr != NULL);
    if (newPtr == NULL)
    {
        exit(-1);
    }

    ps->elem = newPtr;
    newPtr = NULL;

    for (int i = count; i < ps->listsize; i++)
    {
        ps->elem[ i ].ptr = i + 1;
    }

    //为申请的空间初始化
    ps->elem[ 0 ].ptr = count;
    ps->elem[ count * 2 - 1 ].ptr = 0;
}

static bool IsFull(psList ps)
{
    return ps->elem[ 0 ].ptr == 0;
}

//从备用链表里申请一个单位空间,备用链表返回空间地址,数组下标
static int myMalloc(psList ps)
{
    //判断空间是否不足
    if (IsFull(ps))
    {
        inc(ps);
    }

    int p= ps->elem[ 0 ].ptr;
    ps->elem[ 0 ].ptr = ps->elem[ p ].ptr;

    return p;
}

//头插法
bool Insert_head(psList ps, int val)
{
     //p是数据链表向备用链表申请的指针
    int p = myMalloc(ps);

    ps->elem[ p ].data = val;
    //先接头节点之后的链表,头接带p的链表
    ps->elem[ p ].ptr = ps->elem[ 1 ].ptr;
    ps->elem[ 1 ].ptr = p;
    
    return true;
}

//尾插
bool Insert_tail(psList ps, int val)
{  
    int i;
    for ( i = 1; ps->elem[ i ].ptr != 0; i = ps->elem[ i ].ptr);

    int p = myMalloc(ps);
    ps->elem[ p ].data = val;

    ps->elem[ p ].ptr = ps->elem[ i ].ptr;
    ps->elem[ i ].ptr = p;
    return true;
}

//查找
int Search(psList ps, int key)
{
    for (int i = 1; ps->elem[ i ].ptr != 0; i = ps->elem[ i ].ptr)
    {
        if (ps->elem[ ps->elem[ i ].ptr ].data == key)
        {
            return ps->elem[ i ].ptr;
        }
    }
    return 0;
}

//从静态链表中释放这个结点
static void Myfree(psList ps, int p)
{

    ps->elem[ p ].ptr = ps->elem[ 0 ].ptr;
    ps->elem[ 0 ].ptr = p;
}
/*
    找到key结点 查找到key前驱节点
    删除key结点 从数据链表中释放key结点
*/
//删除
bool Delete(psList ps, int key)
{
    int p = GetPrio(ps, key);
    if (p == 0)
    {
        //未找到该节点
        return true;
    }

    //q当前删除的节点
    int q = ps->elem[ p ].ptr;

    ps->elem[ p ].ptr = ps->elem[ q ].ptr;
    Myfree(ps,q);  
}

bool IsEmpty(psList ps)
{
    return ps->length == 0;
}

//获取长度,数据个数
int GetLength(psList ps)
{
    return ps->length;
}

void Show(psList ps)
{
    for (int i = 1; ps->elem[ i ].ptr != 0; i=ps->elem[i].ptr)
    {
        printf("%d ", ps->elem[ps->elem[ i ].ptr].data);
    }
    printf("\n");
}

//获得key的前驱
int GetPrio(psList ps, int key)
{
    for (int i = 1; ps->elem[ i ].ptr != 0; i = ps->elem[ i ].ptr)
    {
        if (ps->elem[ ps->elem[ i ].ptr ].data == key)
        {
            return i;
        }
    }
    //未找到这个节点
    return 0;
}

//获取key后继
int GetNext(psList ps, int key)
{
    for (int i = ps->elem[ 1 ].ptr; i != 0; i = ps->elem[ i ].ptr)
    {
        if (ps->elem[ i ].data == key)
        {
            return ps->elem[ i ].ptr;
        }
    }
    //未找到这个节点
    return 0;
}

//清空数据,容量是否需要恢复到初始状态
void Clear(psList ps)
{
    Destroy(ps);
    InitsList(ps);
}

//销毁ps,释放内存
void Destroy(psList ps)
{
    free(ps->elem);
    ps->elem = NULL;
    ps->length = 0;
    ps->listsize = 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值