C_数据结构_链表的链式实现

 

传统的链表不能实现数据和链表的分离,一旦数据改变则链表就不能用了,就要重新开发。

 如上说示:外层是Teacher,里面小的是node.

#ifndef _MYLINKLIST_H_
#define _MYLINKLIST_H_

typedef void LinkList;//链表上下文,任意类型

typedef struct _tag_LinkListNode
{
    struct _tag_LinkListNode* next;//包含下一个节点的地址
}LinkListNode;//节点



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
#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "linklist.h"

typedef struct _tag_LinkList//这个链表的上下文信息,类似于handle.这里面是链表的头结点和链表的长度。
{
    LinkListNode header;
    int        length;
}TLinkList;



LinkList* LinkList_Create()  //O(1)
{
    TLinkList *tmp = NULL;

    tmp = (TLinkList *)malloc(sizeof(TLinkList));
    if (tmp == NULL)
    {
        printf("func LinkList_Create() err \n");
        return NULL;
    }
    memset(tmp, 0, sizeof(TLinkList));
    tmp->length = 0;
    tmp->header.next = NULL; //
    return tmp;
}

void LinkList_Destroy(LinkList* list)  //O(1)
{
    if (list == NULL)
    {
        return ;
    }
    free(list);//只把上下文信息释放。因为加进去的Teacher对象是局部的,main函数执行完后会自动释放,所以这里不用手动释放。
    return ;
}

void LinkList_Clear(LinkList* list)   //O(1)
{
    TLinkList *tList = NULL;
    tList = (TLinkList *)list;
    if (tList == NULL)
    {
        return ;
    }
    tList->header.next = NULL;
    tList->length = 0;

    return ;
}

int LinkList_Length(LinkList* list)  //O(1)
{
    TLinkList *tList = NULL;
    tList = (TLinkList *)list;
    if (tList == NULL)
    {
        return -1;
    }
    return tList->length;
}

int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)  //在pos位置插入节点,先连接后面的再连接前面的。
{
    int                i = 0;
    LinkListNode    *current = NULL;
    TLinkList        *tList = NULL;
    if (list==NULL || node==NULL || pos<0)//node为新节点
    {
        return -1;
    }
    tList = (TLinkList *)list;
    
    

    current = &(tList->header);//节点要取地址给指针
    for (i=0; i<pos; i++)//链表节点序号从0开始
    {
        current = current->next;//current为pos位置前面的节点
    }
    //先连接后面节点在连接前面节点
    node->next = current->next;

    //前面的链表 连接 新结点
    current->next = node;

    tList->length ++;
    return 0;
}

LinkListNode* LinkList_Get(LinkList* list, int pos)  //O(n)
{
    int                i = 0;
    LinkListNode    *current = NULL;
    TLinkList        *tList = NULL;

    tList = (TLinkList *)list;

    if (list==NULL || pos<0)
    {
        return NULL;
    }

    current = &(tList->header); //赋值指针变量初始化
    for (i=0; i<pos; i++)
    {
        current = current->next;
    }
    return current->next;
}

LinkListNode* LinkList_Delete(LinkList* list, int pos) //O(n)
{
    int                i = 0;
    LinkListNode    *current = NULL;
    LinkListNode    *ret = NULL;
    TLinkList        *tList = NULL;

    tList = (TLinkList *)list;
    if (list==NULL || pos<0)
    {
        return NULL;
    }

    current = &(tList->header);
    for (i=0; i<pos; i++)
    {
        current = current->next;
    }
    ret = current->next; //缓存要删除的结点

    current->next = ret->next;

    tList->length --;

    return ret;
}
#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "linklist.h"


/*
typedef struct _Node
{
    struct _Node *next;
}Node;

typedef struct _Teacher1
{
    char    name[32];
    int        age ;
    Node node;
}Teacher1;


typedef struct _Teacher2
{
    Node node;
    char    name[32];
    int        age ;
    
}Teacher2;

Teacher2 t2;
*/

typedef struct _Teacher
{
    LinkListNode node;    //偏移量:从node元素找到Teacher的地址。写到上面则node的内存首地址和Teacher对象的内存首地址重叠了。
    char        name[32];
    int            age ;
}Teacher;


void main()
{
    LinkList    *list = NULL;
    int            i = 0;

    Teacher t1, t2, t3, t4, t5, t6;//main函数结束这几个变量释放
    t1.age = 31;
    t2.age = 32;
    t3.age = 33;
    t4.age = 34;
    t5.age = 35;
    t6.age = 36;

    list = LinkList_Create();

    //思考1: 业务节点 和 链表算法是如何分离
    //思考2:  业务节点的生命周期 归谁管...


    //插入元素
    LinkList_Insert(list, (LinkListNode *)&t1, 0);//t1地址和node地址是重叠的
    LinkList_Insert(list, (LinkListNode *)&t2, 0);
    LinkList_Insert(list, (LinkListNode *)&t3, 0);
    LinkList_Insert(list, (LinkListNode *)&t4, 0);
    LinkList_Insert(list, (LinkListNode *)&t5, 0);
    LinkList_Insert(list, (LinkListNode *)&t6, 3);


    //遍历链表
    for (i=0; i<LinkList_Length(list); i++)
    {
        Teacher *tmp = (Teacher *)LinkList_Get(list, i);
        if (tmp == NULL)
        {
            return ;
        }
        printf("age:%d \n", tmp->age);
    }


    //删除链表结点
    while (LinkList_Length(list) > 0)
    {
        Teacher *tmp = (Teacher *)LinkList_Delete(list, 0);
        if (tmp == NULL)
        {
            return ;
        }
        printf("age:%d \n", tmp->age);
    }

    LinkList_Destroy(list);


    printf("hello...\n");
    system("pause");
    return ;
}

 

posted @ 2015-09-12 21:10  无天666  阅读(336)  评论(0编辑  收藏  举报