Linked List的基本操作(创建/删除/插入/查找)

Linked list这种数据结构,主要用于对数据进行操作。链表长成下面这样,由多个节点串起来,每个节点有两个域,一个是数据域(用于存储你的数据),一个是指针域(用于存储指向下一个节点的指针),最后一个节点一般指向NULL。

这里写图片描述

那么再看下面这张图

这里写图片描述

从上图可以看出,每个节点之间的地址不是连续的,这个地址是由系统分配的(用malloc创建节点的时候,系统会给该节点分配内存,而每一块内存都有对应的地址)。如a1的指针域是800,而a2的起始地址是800,说明a1的下一个节点就是a2,以此类推,a4的下一个节点是a5,a5是最后一个节点(一般系统会默认NULL为0地址,而a5的指针域指向的是0)

链表基本操作有创建/插入/删除/查找,下面,用两张图来说明插入和删除的操作原理:

这里写图片描述

这里写图片描述

有些人为了方便链表的操作,经常会给链表添加一个头结点做处理,见下图

这里写图片描述

至于头结点的意义在哪里,详见 链表头结点存在的意义

下面我们就直接看代码的实现

linked_list.c
#include <stdio.h>
#include <stdlib.h>
#include "typedef.h"
#include "linked_list.h"

LINK_LIST_T link_list_init(VOID)
{
    LINK_LIST_T pList = (LINK_LIST_T)malloc(sizeof(NODE_T)); 
    if(!pList)
    {
        printf("link_list_init malloc failed! \n");
        return NULL;
    }

    pList->next = NULL;

    return pList;
}

BOOL link_list_is_empty(LINK_LIST_T pList)
{    
    LINK_LIST_CHK_FAIL(pList, TRUE);

    return pList->next == NULL;
}

BOOL link_list_is_last(ElementType element, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, FALSE);

    LINK_LIST_T pTemp = pList;

    while(pTemp->next != NULL)      // fine the last node
        pTemp = pTemp->next;

    if(pTemp->element == element)
        return TRUE;
    else 
        return FALSE;
}

/****************************************************************************
***
*** Check the element in the list or not, if find, return TRUE, if not find, return FALSE
***
****************************************************************************/
BOOL link_list_find_element(ElementType element, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, FALSE);

    LINK_LIST_T pTemp = pList->next;

    while(pTemp)
    {
        if(pTemp->element == element)
            return TRUE;
        pTemp = pTemp->next;
    }

    return FALSE;
}

/****************************************************************************
***
*** Check the element in the list or not, if find, return the index, if not find, return 0
***
****************************************************************************/
INT32 link_list_find_element_ret_index(ElementType element, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, LISTR_FAIL);

    LINK_LIST_T pTemp = pList->next;
    INT32 index = 0;

    while(pTemp)
    {
        index++;
        if(pTemp->element == element)
            return index;
        pTemp = pTemp->next;
    }

    return 0;
}

/****************************************************************************
***
***  Find the element by the index, if find, it can get the element, if not, return FALSE
***
****************************************************************************/
BOOL link_list_find_by_index(ElementType *element, INT32 index, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, FALSE);

    LINK_LIST_T pTemp = pList->next;
    INT32 i = 1;

    while(pTemp && i<index)
    {
        pTemp = pTemp->next;
        i++;
    }

    if(!pTemp || i>index)
    {
        printf("Cannot find the index, invalid args!\n");
        return FALSE;
    }

    *element = pTemp->element;

    return TRUE;
}

POSITION link_list_find_previous(ElementType element, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, NULL);

    LINK_LIST_T pTemp = pList;
    LINK_LIST_T qTemp =  pTemp;

    while(pTemp && pTemp->element != element)
    {
        qTemp = pTemp;
        pTemp = pTemp->next;
    }

    if(!pTemp)
    {
        printf("Cannot find the element in the list!\n");
        return NULL;
    }

    return qTemp;
}

INT32 link_list_insert_at_tail(ElementType element, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, LISTR_FAIL);

    LINK_LIST_T pTemp = pList;

    while(pTemp->next  != NULL)
    {
       pTemp = pTemp->next;
    }

    LINK_LIST_T node = (LINK_LIST_T)malloc(sizeof(NODE_T));
    if(!node)
    {
        printf("link_list_insert_at_tail malloc failed! \n");
        return LISTR_FAIL;
    }

    node->element = element;
    node->next = NULL;

    pTemp->next= node;   

   return LISTR_OK;
}

INT32 link_list_insert_at_head(ElementType element, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, LISTR_FAIL);

    LINK_LIST_T pTemp = pList;
    LINK_LIST_T pNext = pList->next;

    LINK_LIST_T node = (LINK_LIST_T)malloc(sizeof(NODE_T));
    if(!node)
    {
        printf("link_list_insert_at_head malloc failed! \n");
        return LISTR_FAIL;
    }

    node->element = element;
    node->next = pNext;

    pTemp->next= node;   

    return LISTR_OK;
}

INT32 link_list_insert_by_index(ElementType element, INT32 index, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, LISTR_FAIL);

    LINK_LIST_T pTemp = pList;
    INT32 i = 1; 

    while(pTemp && i<index)
    {
        pTemp = pTemp->next;
        i++;
    }

    if(!pTemp || i>index)
    {
        printf("The index is not exist! \n");
        return LISTR_FAIL;        
    }

    LINK_LIST_T node = (LINK_LIST_T)malloc(sizeof(NODE_T));
    if(!node)
    {
        printf("link_list_insert_at_head malloc failed! \n");
        return LISTR_FAIL;
    }

    node->element = element;
    node->next = pTemp->next;
    pTemp->next = node;

    return LISTR_OK;
}

INT32 link_list_delete_by_index(ElementType *element, INT32 index, LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, LISTR_FAIL);

    LINK_LIST_T pTemp = pList;
    LINK_LIST_T qTemp;
    INT32 i=1;

    while(pTemp->next && i<index)
    {
        pTemp = pTemp->next;
        i++;
    }

    if(pTemp->next == NULL || i>index)
    {
        printf("The index is not exist\n");
        return LISTR_FAIL;
    }

    qTemp = pTemp->next;
    *element = qTemp->element;
    pTemp->next = qTemp->next;

    free(qTemp);

    return LISTR_OK;
}

INT32 link_list_get_list_len(LINK_LIST_T pList)
{    
    LINK_LIST_CHK_FAIL(pList, LISTR_FAIL);

    LINK_LIST_T pTemp = pList;
    INT32 len = 0;

    if(!pList)
    {
        printf("The link list is uninit, pls init it\n");
        return LISTR_FAIL;
    }

    while(pTemp->next)
    {
        len++;
        pTemp = pTemp->next;
    }

    return len;
}

INT32 link_list_uninit(LINK_LIST_T pList)
{
    LINK_LIST_T pTemp;

    while(pList)
    {        
        pTemp = pList->next;
        free(pList);
        pList = pTemp;
    }

    return LISTR_OK;
}

VOID link_list_traverse(LINK_LIST_T pList)
{
    LINK_LIST_CHK_FAIL(pList, (void)LISTR_FAIL);

    LINK_LIST_T pTemp = pList->next;

    while(pTemp != NULL)
    {
        printf("node->element : %d\n", pTemp->element);
        pTemp = pTemp->next;
    }
}


VOID link_list_main_test(VOID)
{
    INT32 i;
    LINK_LIST_T pList = link_list_init();

    for(i=1; i<=10; i++)
        link_list_insert_at_tail(i, pList);

    link_list_traverse(pList);    

    if(pList)
    {
        link_list_uninit(pList);
    }
}
linked_list.h
#ifndef __LINKED_LIST_H__
#define __LINKED_LIST_H__

typedef int ElementType;

typedef struct _NODE_T
{
    ElementType element;
    struct _NODE_T *next;
}NODE_T;

typedef struct _NODE_T * LINK_LIST_T;
typedef struct _NODE_T * POSITION;

#define LISTR_OK                              ((INT32)0)
#define LISTR_FAIL                            ((INT32)-1)

#define LINK_LIST_CHK_FAIL(argu, value)     if(!(argu)) {printf("<LINK_LIST> ERR : func=%s, line=%d, argument="#argu".\n", __func__, __LINE__); return value;}


extern LINK_LIST_T link_list_init(VOID);
extern BOOL link_list_is_empty(LINK_LIST_T pList);
extern BOOL link_list_is_last(ElementType element, LINK_LIST_T pList);
extern BOOL link_list_find_element(ElementType element, LINK_LIST_T pList);
extern INT32 link_list_find_element_ret_index(ElementType element, LINK_LIST_T pList);
extern BOOL link_list_find_by_index(ElementType *element, INT32 index, LINK_LIST_T pList);
extern POSITION link_list_find_previous(ElementType element, LINK_LIST_T pList);
extern INT32 link_list_insert_at_tail(ElementType element, LINK_LIST_T pList);
extern INT32 link_list_insert_at_head(ElementType element, LINK_LIST_T pList);
extern INT32 link_list_insert_by_index(ElementType element, INT32 index, LINK_LIST_T pList);
extern INT32 link_list_delete_by_index(ElementType *element, INT32 index, LINK_LIST_T pList);
extern INT32 link_list_get_list_len(LINK_LIST_T pList);
extern INT32 link_list_uninit(LINK_LIST_T pList);
extern VOID link_list_traverse(LINK_LIST_T pList);
extern VOID link_list_main_test(VOID);

#endif

PS:本文所用的图片全都引用自《数据结构与算法分析C语言描述 第2版》第三章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值