C 实现双链表

DoublyLinkedList.h

#pragma once

// 新建双向链表。成功,返回0;否则,返回-1。
extern int DLink_Create();

// 链表大小
extern int DLink_Size();

// 获取第index位置的节点的值。
extern void* DLink_GetValue(int index);

// 表头插入数据
extern int DLink_InsertFirst(void *pval);

// 表尾插入数据
extern int DLink_InsertLast(void *pval);

// 在第index位置插入数据
extern int DLink_Insert(int index, void *pval);

// 删除双链表的第一个节点
extern int DLink_DeleteFirst();

// 删除双链表的最后一个节点
extern int DLink_DeleteLast();

// 删除双链表的第index个节点
extern int DLink_Delete(int index);

// 销毁双向链表。成功,返回0;否则,返回-1。
extern int DLink_Destory();

DoublyLinkedList.c

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

// 双向链表节点
typedef struct node
{
    struct node *prev;
    struct node *next;
    void *p;
}node;

// 头结点,头结点不保存数据
static node *phead = NULL;

// 节点个数
static int count = 0; 

// 新建节点。成功,返回节点指针;否则,返回NULL。
static node* CreateNode(void *pval)
{
    node *pnode = NULL;
    pnode = (node*)malloc(sizeof(node));
    if (pnode == NULL)
    {
        printf("Create Node Failed!\n");
        return NULL;
    }
    // 初始化新建节点前置节点和后置节点都是自己
    pnode->prev = pnode->next = pnode;
    // 节点的值可为任何类型
    pnode->p = pval;

    return pnode;
}

// 新建双向链表。成功,返回0;否则,返回-1。
int DLink_Create()
{
    // 创建表头
    phead = CreateNode(NULL);
    if (phead == NULL)
        return -1;

    count = 0;

    return 0;
}

// 链表大小
int DLink_Size()
{
    return count;
}

// 获取第index位置的节点。 0 <= index < count
static node* GetNode(int index)
{
    if (index < 0 || index >= count)
    {
        printf("%s failed! Index is out of range!\n", __func__);
        return NULL;
    }

    /// count = 6
    ///   ↓—————————————————————————————————————————————————↑
    ///  □□□  <-> □□□ <-> □□□ <-> □□□ <-> □□□ <-> □□□ <-> □□□ 
    ///  ↓—————————————————————————————————————————————————↑
    ///  head      0       1       2       3       4       5

    // 正向查找
    if(index < (count/2))
    {
        int i = 0;
        node *pnode = phead->next;
        while ((i++) < index)
            pnode = pnode->next;

        return pnode;
    }

    // 反向查找
    int i = count - 1;
    node *pnode = phead->prev;
    while ((i--) > index)
        pnode = pnode->prev;

    return pnode;
}

// 获取第index位置的节点的值。
void* DLink_GetValue(int index)
{
    node *pnode = GetNode(index);
    if (pnode == NULL)
    {
        printf("%s failed!\n", __func__);
        return NULL;
    }
    return pnode->p;
}

// 表头插入数据
int DLink_InsertFirst(void *pval)
{
    node *pnode = CreateNode(pval);
    if (pnode == NULL)
        return -1;

    pnode->next = phead->next;
    pnode->prev = phead;
    phead->next->prev = pnode;
    phead->next = pnode;

    count++;
    return 0;
}

// 表尾插入数据
int DLink_InsertLast(void *pval)
{
    node *pnode = CreateNode(pval);
    if (pnode == NULL)
        return -1;

    pnode->next = phead;
    pnode->prev = phead->prev;
    phead->prev->next = pnode;
    phead->prev = pnode;

    count++;
    return 0;
}

// 在第index位置插入数据
int DLink_Insert(int index, void *pval)
{
    if (index == 0)
        return DLink_InsertFirst(pval);

    node *pIndex = GetNode(index);
    if (pIndex == NULL)
        return -1;

    node *pnode = CreateNode(pval);
    if (pnode == NULL)
        return -1;

    pnode->next = pIndex->next;
    pnode->prev = pIndex;
    pIndex->next->prev = pnode;
    pIndex->next = pnode;

    count++;
    return 0;
}

// 删除双链表的第一个节点
int DLink_DeleteFirst()
{
    return DLink_Delete(0);
}

// 删除双链表的最后一个节点
int DLink_DeleteLast()
{
    return DLink_Delete(count - 1);
}

// 删除双链表的第index个节点
int DLink_Delete(int index)
{
    node *pindex = GetNode(index);
    if (pindex == NULL)
    {
        printf("%s failed!", __func__);
        return -1;
    }

    pindex->next->prev = pindex->prev;
    pindex->prev->next = pindex->next;
    free(pindex);
    count--;
    return 0;
}

// 销毁双向链表。成功,返回0;否则,返回-1。
int DLink_Destory()
{
    if (phead == NULL)
    {
        printf("%s failed!\n", __func__);
        return -1;  
    }

    node *pnode = phead->next;
    node *ptmp = NULL;
    while (pnode != phead)
    {
        ptmp = pnode;
        pnode = pnode->next;
        free(ptmp);
    }
    free(phead);
    phead = NULL;
    count = 0;
    return 0;
}

DoublyLinkedList_Test.c

#include <stdio.h>
#include <DoublyLinkedList.h>

void int_test()
{
    int iarr[4] = { 10, 20, 30, 40 };
    printf("\n----%s----\n", __func__);
    DLink_Create();             // 创建双链表

    DLink_Insert(0, &iarr[0]);  // 在表头插入数据
    DLink_Insert(0, &iarr[1]);  // 在表头插入数据
    DLink_Insert(0, &iarr[2]);  // 在表头插入数据
    DLink_Insert(0, &iarr[3]);  // 在表头插入数据

    printf("This list`s size is %d\n", DLink_Size());

    // 打印全部数据
    int *p;
    int size = DLink_Size();
    for (int i = 0; i < size; i++)
    {
        p = (int*)DLink_GetValue(i);
        printf("第%d个元素为:%d\n", i, *p);
    }
    DLink_Destory();
}

void string_test()
{
    char* sarr[4] = { "ten","tweny","thiry", "forty" };
    printf("\n----%s----\n", __func__);
    DLink_Create();

    DLink_Insert(0, sarr[0]);
    DLink_Insert(0, sarr[1]);
    DLink_Insert(0, sarr[2]);
    DLink_Insert(0, sarr[3]);

    printf("This list`s size is %d\n", DLink_Size());

    char *p;
    int size = DLink_Size();
    for (int i = 0; i < size; i++)
    {
        p = (char*)DLink_GetValue(i);
        printf("第%d个元素为:%s\n", i, p);
    }
    DLink_Destory();
}

typedef struct stu
{
    int id;
    char name[20];
}stu;

static stu arr_stu[] =
{
    {10,"andy"},
    {20,"baby"},
    {30,"city"},
    {40,"dog"},
};

#define ARR_STU_SIZE ((sizeof(arrstu))/(sizeof(arrstu[0])))

void object_test()
{
    printf("\n----%s----\n", __func__);
    DLink_Create();

    DLink_Insert(0, &arr_stu[0]);
    DLink_Insert(0, &arr_stu[1]);
    DLink_Insert(0, &arr_stu[2]);
    DLink_Insert(0, &arr_stu[3]);

    printf("This list`s size is %d\n", DLink_Size());

    stu *p;
    int size = DLink_Size();
    for (int i=0;i<size;i++)
    {
        p = (stu*)DLink_GetValue(i);
        printf("第%d个元素是[%d,%s]\n", i, p->id, p->name);
    }
    DLink_Destory();
}

int main()
{
    int_test();
    string_test();
    object_test();
    printf("\n");
    system("pause");
    return 0;
}

测试结果

这里写图片描述

参考:http://wangkuiwu.github.io/2013/01/01/dlink/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值