二、创建一个可复用的单链表

一、LinkList.h


#ifndef  _LINKLIST_H_
#define  _LINKLIST_H_


typedef    void   LinkList;    //定义LinkList为空类型
typedef     struct   _tag_LinkListNode      LinkListNode;     //结点指针域的定义  
struct   _tag_LinkListNode       
{
       LinkListNode*    next;
}


LinkList*   LinkList_Create();    //创建单链表


void   LinkList_Destroy(LinkList*   list);    //销毁单链表
void   LinkList_Clear(LinkList*   list);        //清空单链表的元素
int   LinkList_Length(LinkList*   list);        //获取当前单链表的元素个数


int LinkList_Insert(LinkList*  list,LinkListNode* node,int  pos);    //在单链表某个位置插入某个元素
LinkListNode*   LinkList_Get(LinkList*  list, int  pos);                  //获取单链表某个位置的元素
LinkListNode*      LinkList_Delete(LinkList*  list,int  pos);             //删除单链表的某个元素


#endif




二、LinkList.c


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


typedef     struct  _tag_LinkList               //头结点的定义
{
    LinkList Node    header;
   int   length;
}TLinkList;






LinkList*    LinkList_Create()
{
    TLinkList *  ret=(*LinkList*)malloc(szie(TLinkList));   // 动态申请空间
     if(ret!=NULL)                      //判断是否为空
      {
          ret->length=0;               //初始化元素的个数为0
          ret->header.next=NULL;         //单链表的头结点指向空
      }
  return    ret;
}


void  LinkList_Destroy(LinkList*  list)
{
    free(list);          //销毁单链表
}


void  LInkList_Clear(LinkList* list)
{
    TLinkList*  sList=(TLinkList*)  list;    将单链表头结点的信息进行强制转化为TLinkList*
    if(sList!=NULL)      //判断链表是否为空
   {
        sList->length=0;      //将元素个数清零
        sList->header.next=NULL;   //头结点信息指向为null
   }
}


int  LinkList_Length(LinkList*  list)
{
    TLinkList*  sList=(TLinkList*)  List;      //将头结点的信息进行强制转化才能使用
    int  ret=-1;          //当获取不了当前的长度,返回错误提示
    if(sList!=NULL)      //判断链表是否为空
     {
              ret=sList->length;    将链表当前长度赋值给ret
      }
         return      ret;
}


int  LinkList_Insert(LinkList*  list,LinkListNode*  node,int   pos)
{
      TLinkList*   sList=(TLinkList*)List;   //进行链表的头结点的强制转化
       int ret=(list!=NULL&&pos>=0&&node!=NULL);       
       int i=0;
       if(ret)     //判断链表和插入元素的地址是否为空以及插入的位置是否有效,三者同时成立即可进入
        {
               LinkListNode*   current=(LinkListNode*)sList;     //定义current指针指向我们的头结点
              for(i=0;(i<pos)&&(current->next !=NULL);i++)       //进行循环处理,current指针从指向头结点,依次向后移动,直到current指针指向pos位置的前一个元素时,结束循环
                {
                        current=current->next;
                }
               node->next=current->next;     //将插入的元素指向的下一个元素为pos位置后面的元素
                current->next=node;              //将pos后面的元素指针指向插入元素的地址
               sList->length++;                     //长度加一
        }
              return   ret; 
}


LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n)
{
    TLinkList* sList = (TLinkList*)list;    //进行链表头结点的强制转换
    LinkListNode* ret = NULL;       
    int i = 0;
    
    if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )
    {
        LinkListNode* current = (LinkListNode*)sList;    //将current指向头结点
        
        for(i=0; i<pos; i++)          //循环处理将得到获得我们想要元素的前一个元素的地址
        {
            current = current->next;
        }
        
        ret = current->next;           //current->next的地址就是我们要获取到的元素地址
    }
    
    return ret;
}




LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n)
{
    TLinkList* sList = (TLinkList*)list;    ///强制转换头结点信息
    LinkListNode* ret = NULL;               //ret初始化
    int i = 0;
    
    if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )   //进行条件判断
    {
        LinkListNode* current = (LinkListNode*)sList;                    // 将current指针指向头结点的信息
        
        for(i=0; i<pos; i++)            
        {
            current = current->next;
        }
        
        ret = current->next;      //把将删除元素的地址通过current赋给ret
        current->next = ret->next;    //   将删除的元素,前一个的指针域指向删除元素的后一个元素的地址
        
        sList->length--;
    }
    
    return ret;

}

三、main.c


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

struct Value
{
    LinkListNode header;
    int v;
};


int main(int argc, char *argv[]) 
{
    int i = 0;
    LinkList* list = LinkList_Create();
    
    struct Value v1;
    struct Value v2;
    struct Value v3;
    struct Value v4;
    struct Value v5;
    
    v1.v = 1;
    v2.v = 2;
    v3.v = 3;
    v4.v = 4;
    v5.v = 5;
    
    LinkList_Insert(list, (LinkListNode*)&v1, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v2, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v3, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v4, LinkList_Length(list));
    LinkList_Insert(list, (LinkListNode*)&v5, LinkList_Length(list));
    
    for(i=0; i<LinkList_Length(list); i++)
    {
        struct Value* pv = (struct Value*)LinkList_Get(list, i);
        
        printf("%d\n", pv->v);
    }
    
    while( LinkList_Length(list) > 0 )
    {
        struct Value* pv = (struct Value*)LinkList_Delete(list, 0);
        
        printf("%d\n", pv->v);
    }
    
    LinkList_Destroy(list);
    
    return 0;
}


运行结果:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值