双向链表c语言实现 doublelinklist.h 和 doublelinklist.c

doublelinklist.h 文件

#ifndef _DOUBLE_LINK_LIST_H_
#define _DOUBLE_LINK_LIST_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//链表就是一个一个的表通过关系节点连接的
//双向链表
//链表操作精髓在于操作关系节点,引入辅助指针pcurrent,pnext.从表头开始遍历各关系节点。

typedef void List;
typedef void ListNode;


#ifndef bool
#define bool int
#define true 1
#define false 0
#endif

//定义双向链表的关系小节点
typedef struct _tag_DoubleLinkListConnectedNode
{
    struct _tag_DoubleLinkListConnectedNode* next;
    struct _tag_DoubleLinkListConnectedNode* pre;
}DoubleLinkListConnectedNode;

typedef struct _tag_DoubleLinkList
{
    DoubleLinkListConnectedNode head;
    DoubleLinkListConnectedNode* slider;
    int length;
}DoubleLinkList;

List* DoubleLinkList_Create();
bool DoubleLinkList_Destory(List* list );
bool DoubleLinkList_Clear(List* list);
int DoubleLinkList_GetLength(List* list);
bool DoubleLinkList_InsertOneNode(List* list,ListNode* listnode,int pos);
ListNode* DoubleLinkList_GetOneNode(List* list, int pos);
ListNode* DoubleLinkList_DeleteOneNode(List* list ,int pos);
bool DoubleLinkList_DeleteAllNode(List* list);
ListNode* DoubleLinkList_DeleteOneNodeByNodePointer(List* list,ListNode* listnode);
ListNode* DoubleLinkList_ResetSlider(List* list);
ListNode* DoubleLinkList_GetCurrentSlider(List* list);
ListNode* DoubleLinkList_SliderMoveToNext(List* list);

#endif

doublelinklist.c 文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "doublelinklist.h"
//链表就是一个一个的表通过关系节点连接的
//链表操作精髓在于操作关系节点,引入辅助指针pcurrent,pnext.从表头开始遍历各关系节点。

List* DoubleLinkList_Create()
{
    List* ret = NULL;
    DoubleLinkList* temp_doublelinklist = NULL;
    temp_doublelinklist = (DoubleLinkList*)malloc(sizeof(DoubleLinkList));
    if (temp_doublelinklist == NULL)
    {
        return NULL;
    }
    temp_doublelinklist->head.next = NULL;
    temp_doublelinklist->head.pre = NULL;
    temp_doublelinklist->slider = NULL;
    temp_doublelinklist->length = 0;
    ret = (List*)temp_doublelinklist;
    return ret;
}

bool DoubleLinkList_Destory(List* list )
{
    DoubleLinkList* temp_doublelinklist = NULL;
    if (list == NULL)
    {
        return false;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    free(temp_doublelinklist);
    temp_doublelinklist = NULL;
    return true;
}

bool DoubleLinkList_Clear(List* list)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    if (list == NULL)
    {
        return false;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    temp_doublelinklist->head.next = NULL;
    temp_doublelinklist->head.pre = NULL;
    temp_doublelinklist->slider = NULL;
    temp_doublelinklist->length = 0;
    return true;
}

int DoubleLinkList_GetLength(List* list)
{
    int ret = 0;
    DoubleLinkList* temp_doublelinklist = NULL;
    if (list == NULL)
    {
        return -1;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    ret = temp_doublelinklist->length;
    return ret;
}

bool DoubleLinkList_InsertOneNode(List* list,ListNode* listnode,int pos)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnectednode_insert = NULL;
    DoubleLinkListConnectedNode* pcurrent = NULL;   //辅助指针
    DoubleLinkListConnectedNode* pnext = NULL;      //辅助指针的下一节点
    int i = 0;
    if (list == NULL || listnode == NULL || pos < 0)
    {
        return false;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    temp_doublelinklistconnectednode_insert = (DoubleLinkListConnectedNode*)listnode;
    //辅助指针指向链表头部即首地址
    pcurrent = (DoubleLinkListConnectedNode*)temp_doublelinklist;
    //辅助指针跳到pos-1处
    for (i = 0; (i < pos && pcurrent->next != NULL); i++)
    {
        pcurrent = pcurrent->next;
    }
    //pcurrent 为要 插入节点 的前一节点,pnext为要 插入节点 的后一节点
    //pcurrent  pnext 三者的顺序关系 listnode插入前
    //pcurrent listnode pnext     listnode插入后
    //得到pnext
    pnext = pcurrent->next;
    //开始插入新节点 
    //正向连
    pcurrent->next = temp_doublelinklistconnectednode_insert;
    temp_doublelinklistconnectednode_insert->next = pnext;
    //反向连时 判断pnext是否为空,就是表头后面插入第一个节点时要处理
    if (pnext != NULL)
    {
        pnext->pre = temp_doublelinklistconnectednode_insert;
    }
    temp_doublelinklistconnectednode_insert->pre = pcurrent;
    //第一次插入时,游标指向第一个插入的节点
    if (temp_doublelinklist->length == 0)
    {
        temp_doublelinklist->slider = temp_doublelinklistconnectednode_insert;
    }
    //第一次插入的节点即0号位置的节点pre为null,插入的节点指向null
    if (pcurrent == (DoubleLinkListConnectedNode*)temp_doublelinklist)
    {
        temp_doublelinklistconnectednode_insert->pre = NULL;
    }
    temp_doublelinklist->length++;
    return true;
}

ListNode* DoubleLinkList_GetOneNode(List* list, int pos)
{

    ListNode* ret = NULL;
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnectednode = NULL;
    DoubleLinkListConnectedNode* pcurrent = NULL;   //辅助指针
    int i = 0;
    if (list == NULL || pos < 0)
    {
        return NULL;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    if (temp_doublelinklist->length <= 0 || pos >= temp_doublelinklist->length)
    {
        return NULL;
    }
    //辅助指针指向链表头部即首地址
    pcurrent = (DoubleLinkListConnectedNode*)temp_doublelinklist;
    //辅助指针跳到pos-1处
    for (i = 0; (i < pos && pcurrent->next != NULL); i++)
    {
        pcurrent = pcurrent->next;
    }
    temp_doublelinklistconnectednode = pcurrent->next;
    ret = (ListNode*)temp_doublelinklistconnectednode;
    return ret;
}


ListNode* DoubleLinkList_DeleteOneNode(List* list ,int pos)
{
    ListNode* ret = NULL;
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnectednode_delete = NULL;
    DoubleLinkListConnectedNode* pcurrent = NULL;   //辅助指针
    DoubleLinkListConnectedNode* pnext = NULL;      //辅助指针的下一节点
    int i = 0;
    if (list == NULL || pos < 0)
    {
        return false;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    if (temp_doublelinklist->length <= 0 || pos >= temp_doublelinklist->length)
    {
        return NULL;
    }
    //辅助指针指向链表头部即首地址
    pcurrent = (DoubleLinkListConnectedNode*)temp_doublelinklist;
    //辅助指针跳到pos-1处
    for (i = 0; (i < pos && pcurrent->next != NULL); i++)
    {
        pcurrent = pcurrent->next;
    }
    //得到pcurrent 和 pnext
    temp_doublelinklistconnectednode_delete = pcurrent->next;
    pnext = temp_doublelinklistconnectednode_delete->next;
    //连线连接
    pcurrent->next = pnext;

    //判断链表中是否只有一个业务节点
    //如果只有一个pcurrent即头部直接指向空就处理完毕,上一句就可以搞定了
    //pnext不为空,不止一个业务节点
    if (pnext != NULL)
    {
        pnext->pre = pcurrent;
        //0号位置的节点删除后,补上来的节点特殊处理
        if (pcurrent == (DoubleLinkListConnectedNode*)temp_doublelinklist)
        {
            pnext->pre = NULL;
        }
    }

    //删除游标指向的节点,游标指向下一个节点
    if (temp_doublelinklist->slider == temp_doublelinklistconnectednode_delete)
    {
        temp_doublelinklist->slider = pnext;
    }

    temp_doublelinklist->length--;
    ret = (ListNode*)temp_doublelinklistconnectednode_delete;
    return ret;
}

bool DoubleLinkList_DeleteAllNode(List* list)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    if (list == NULL)
    {
        return false;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    while(temp_doublelinklist->length > 0)
    {
        DoubleLinkList_DeleteOneNode((List*)temp_doublelinklist,0);
    }
    return true;
}

ListNode* DoubleLinkList_DeleteOneNodeByNodePointer(List* list,ListNode* listnode)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnected_delete = NULL;
    DoubleLinkListConnectedNode* pcurrent = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnectednode_ret = NULL;
    ListNode* ret = NULL;
    int i = 0;
    if (list == NULL || listnode == NULL)
    {
        return NULL;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    temp_doublelinklistconnected_delete = (DoubleLinkListConnectedNode*)listnode;
    if (temp_doublelinklist->length <= 0)
    {
        return NULL;
    }
    //得到辅助指针pos-1
    pcurrent = (DoubleLinkListConnectedNode*)temp_doublelinklist;
    //找同地址节点时
    for (i = 0; i < temp_doublelinklist->length; i ++ )
    {
        //链表头不存业务节点,此处就可以先指向0位置的业务节点后再判断
        pcurrent = pcurrent->next;
        if (pcurrent == temp_doublelinklistconnected_delete)
        {
            temp_doublelinklistconnectednode_ret = temp_doublelinklistconnected_delete;
            break;
        }

    }
    if (temp_doublelinklistconnectednode_ret == NULL)
    {
        return NULL;
    }
    DoubleLinkList_DeleteOneNode((List*)temp_doublelinklist,i);
    ret = (ListNode*)temp_doublelinklistconnectednode_ret;
    return ret;

}

//重置游标
ListNode* DoubleLinkList_ResetSlider(List* list)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnected_node = NULL;
    ListNode* ret = NULL;
    if (list == NULL)
    {
        return NULL;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    temp_doublelinklist->slider = temp_doublelinklist->head.next;

    temp_doublelinklistconnected_node = temp_doublelinklist->slider;
    ret = (ListNode* )temp_doublelinklistconnected_node;
    return ret;
}

//返回当前游标,
ListNode* DoubleLinkList_GetCurrentSlider(List* list)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnected_node = NULL;
    ListNode* ret = NULL;
    if (list == NULL)
    {
        return NULL;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    temp_doublelinklistconnected_node = temp_doublelinklist->slider;
    ret = (ListNode*)temp_doublelinklistconnected_node;
    return ret;
}

//游标下移,并返回游标下移之前的节点
ListNode* DoubleLinkList_SliderMoveToNext(List* list)
{
    DoubleLinkList* temp_doublelinklist = NULL;
    DoubleLinkListConnectedNode* temp_doublelinklistconnected_node = NULL;
    ListNode* ret = NULL;
    if (list == NULL)
    {
        return NULL;
    }
    temp_doublelinklist = (DoubleLinkList*)list;
    temp_doublelinklistconnected_node = temp_doublelinklist->slider;
    temp_doublelinklist->slider = temp_doublelinklistconnected_node->next;
    ret = (ListNode*)temp_doublelinklistconnected_node;
    return ret;
}


/**************************以下是测试代码*************************/

/*
typedef struct _tag_Teacher
{

    DoubleLinkListConnectedNode node;
    int age ;
    char name[];
}Teacher;

void main()
{
    List* list = NULL;
    Teacher t1,t2,t3,t4,t5;
    int kk = 0;
    Teacher* teacher = NULL;
    t1.age = 21;t2.age = 22;t3.age = 23;t4.age = 24;t5.age = 25;
    list = DoubleLinkList_Create();
    if (list == NULL)
    {
        printf("创建list失败");
    }
    //尾插法
    DoubleLinkList_InsertOneNode(list,(ListNode*)&t1,DoubleLinkList_GetLength(list));
    DoubleLinkList_InsertOneNode(list,(ListNode*)&t2,DoubleLinkList_GetLength(list));
    DoubleLinkList_InsertOneNode(list,(ListNode*)&t3,DoubleLinkList_GetLength(list));
    DoubleLinkList_InsertOneNode(list,(ListNode*)&t4,DoubleLinkList_GetLength(list));
    DoubleLinkList_InsertOneNode(list,(ListNode*)&t5,DoubleLinkList_GetLength(list));

    //
    for (kk = 0; kk < DoubleLinkList_GetLength(list); kk ++)
    {
         teacher = (Teacher* )DoubleLinkList_GetOneNode(list,kk);
         printf("老师%d的年龄是%d",kk,teacher->age);
         printf("\n");
    }
    printf("链表长度%d \n",DoubleLinkList_GetLength(list));

    DoubleLinkList_DeleteOneNodeByNodePointer(list,(ListNode*)&t5);
    //DoubleLinkList_DeleteOneNode(list,0);
    printf("链表长度%d \n",DoubleLinkList_GetLength(list));

    for (kk = 0; kk < DoubleLinkList_GetLength(list); kk ++)
    {
        teacher = (Teacher* )DoubleLinkList_GetOneNode(list,kk);
        printf("老师%d的年龄是%d",kk,teacher->age);
        printf("\n");
    }
    printf("链表长度%d \n",DoubleLinkList_GetLength(list));
    DoubleLinkList_DeleteAllNode(list);
    printf("链表长度%d \n",DoubleLinkList_GetLength(list));
    DoubleLinkList_Destory(list);
    system("pause");
}
*/

可能会调用其它头文件或源文件,如果调用,请翻看我的其它博客,对其头文件或源文件的实现。
good luck !

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值