C语言数据结构,第二节--线性表的连式存储

一、思路:针对线性表的链式存储,其实我们最主要的是要考虑如何将链表节点和业务节点如何合在一起,意思就是我们的链表的API函数,操作的是链表节点,而我们如何将业务节点和链表节点相绑定,这样的话,这样的话我们操作链表节点,其实就是操作的业务节点。

二.通用链表:链表操作还是只操作链表节点,但是链表节点存在业务节点的开始,那么链表节点和业务节点的地址就是相通的,这样可以将业务节点伪装成链表节点。如图所示:

三.对于通用链表模型的删除和插入数据,模型图

四、链表的相关API函数:

头文件定义为:

#ifndef __SEQLIST__H
#define __SEQLIST__H

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

typedef  struct _list_node
{
    struct _list_node *pnext;

}list_node;



typedef struct _seqlist
{
    list_node header;
    int length;
} seqlist;

seqlist* seqlist_create(int cap);
int seqlist_length(seqlist *seq);
list_node * seqlist_get(seqlist *seq,int n);
int  seqlist_insert(seqlist *seq,list_node *node,int n);
list_node *seqlist_delete(seqlist *seq,int n);


#endif  
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "seqlist.h"


seqlist* seqlist_create()
{
    seqlist *tmp = NULL;
    int ret = 0;
    tmp = malloc(sizeof(seqlist));
    if(NULL == tmp)
    {
        ret = -1;
        printf("seqlist_create error :%d \n",ret);
        return NULL;
    }
    tmp->length = 0;
    tmp->header.pnext = NULL;
    return tmp;
}


int seqlist_capacity(seqlist *seq)
{
    int ret = 0;
    if(NULL ==seq)
    {
        ret = -1;
        printf("seqlist_capacity error :%d \n",ret);
        return ret;
    }

    return seq->capacity;
}

int seqlist_length(seqlist *seq)
{
    int ret = 0;
    if(NULL == seq)
    {
        ret = -1;
        printf("seqlist_length error :%d \n",ret);
        return ret;
    }

    return seq->length;
}


list_node * seqlist_get(seqlist *seq,int n)
{
    int ret =0,i = 0;
    if(NULL == seq)
    {
        ret = -1;
        printf("seqlist_get error :%d \n",ret);
        return NULL;
    }
    if(seq->length <=0)
    {
        ret = -3;
        printf("seqlist_get error :%d \n",ret);
        return NULL;
    }
    if(n > seq->length -1)
    {
        ret = -2;
        printf("seqlist_get error :%d \n",ret);
        return NULL;
    }

    list_node * pcurrent = NULL;
    pcurrent = (list_node *)seq;
    
    for(i =0;i <= n;i++)
    {
        pcurrent = pcurrent->pnext;
    }
    return pcurrent;
}



int  seqlist_insert(seqlist *seq,list_node *node,int n)
{
    int i = 0 ,ret = 0;
    if(NULL == seq || NULL == node || n<0)
    {
        ret = -1;
        printf("seqlist_insert errpr :%d \n",ret);
        return ret;
    }

    list_node * pcurrent = (list_node *)seq;
    for(i = 0; i < n;i++)
    {
        pcurrent = pcurrent->pnext;
    }
    if(n == seq->length)   //对于尾部插入也有个特殊处理
    {
        pcurrent ->pnext = node;
        seq->length++;
        node->pnext = NULL;
        return ret;
    }
    seq->length++;
    node->pnext = pcurrent->pnext;
    pcurrent->pnext = node;

    return ret;
}

list_node *seqlist_delete(seqlist *seq,int n)
{
    int i =0,ret = 0;

    if(NULL == seq || n<0 || n>=seq->length)
    {
        ret = -1;
        printf("seqlist_delete error :%d \n",ret);
        return NULL;
    }
    list_node * pcurrent = (list_node *)seq;
    for(i = 0;i < n;i++)
    {
        pcurrent = pcurrent->pnext;
    }

    if(n == seq->length -1)   //对于尾部删除有个特殊处理
    {
        list_node *tmp = pcurrent->pnext;
        pcurrent->pnext = NULL;
        seq->length--;
        return tmp;
    }

    list_node *tmp = pcurrent->pnext;
    pcurrent->pnext = pcurrent->pnext->pnext;

    seq->length--;
    return tmp;

}

总结:

1.链表通用模型关键点在于:将链表节点和业务节点想绑定,通过C语言的指针强制类型转换来实现的;

2.链表的删除和插入,主要关键在于定义一个辅助指针,通过这个辅助指针来实现相关的业务逻辑,这也是比较关键的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值