链表(3)----循环单链表基本操作

1、循环链表基本定义

typedef  struct CListElement_t_{
    void *data;
    struct CListElement_t *next;
} CListElement_t

typedef struct CList_t_ {
    int size;
    int (*match)(const void *key1, const void *key2);
    int (*destroy)(void *data);
    CListElement_t  *head;
    CListElement_t  *tail;
} CList_t;


typedef  struct CListElement_t_{

    void *data;

    struct CListElement_t *next;

} CListElement_t


typedef struct CList_t_ {

    int size;

    int (*match)(const void *key1, const void *key2);

    int (*destroy)(void *data);

    CListElement_t  *head;

    CListElement_t  *tail;

} CList_t;


2、初始化

int clist_init( CList_t *clist, int(*match)(const void*key1, const void *key2), int (*destroy)(void *data))
{
    clist->size = 0;
    clist->match = match;
    clist->destroy = destroy;
    clist->head = NULL;
    clist->tail = NULL;
    return 0;
}


int clist_init( CList_t *clist, int(*match)(const void*key1, const void *key2), int (*destroy)(void *data))

{

    clist->size = 0;

    clist->match = match;

    clist->destroy = destroy;

    clist->head = NULL;

    clist->tail = NULL;

    return 0;

}


3、插入

在给定元素element之后插入

异常情况:

(1)链表已满

    if( clist_is_full( clist ))

        return -1;

(2)新增节点空间分配失败

    if( ( new_element = (CListElement_t *)malloc( sizeof( CListElement_t )) ) == NULL )

        return -2;


常规情况:

(1)如果element为NULL,或者element为尾节点,则插入到头结点前面

        需要考虑链表为空,此时需要维护尾指针

        new_element->next = clist->head;

        clist->head = new_element;

        if(clist_is_empty( clist) )

            clist->tail = new_element; 

        clist->tail->next = clist->head;


(2)如果element不为NULL,插入到element后面

        需要考虑element为尾节点时,此时需要维护尾指针

        new_element->next = element->next;

        element->next = new_element;

int clist_insert_next( CList_t *clist, CListElement_t *element, const void *data )
{
    if( clist_is_full( clist))
        return -1;

    CListElement_t *new_element = NULL;
    if(( new_element = (CListElement_t *)malloc( sizeof( CListElement_t ))) == NULL )
        return -2;

    new_element->data = data;
    new_element->next = NULL;

    if( (element == NULL) || clist_is_tail( clist, element) ){
        new_element->next = clist->head;
        clist->head = new_element;
        if( clist_is_empty( clist ))
            clist->tail = new_element;

        clist->tail->next = clist->head;
    } else {
        new_element->next = element->next;
        element->next = new_element;
    }
    clist->size++;
    return 0;
}


int clist_insert_next( CList_t *clist, CListElement_t *element, const void *data )

{

    if( clist_is_full( clist))

        return -1;


    CListElement_t *new_element = NULL;

    if(( new_element = (CListElement_t *)malloc( sizeof( CListElement_t ))) == NULL )

        return -2;


    new_element->data = data;

    new_element->next = NULL;


    if( (element == NULL) || clist_is_tail( clist, element) ){

        new_element->next = clist->head;

        clist->head = new_element;

        if( clist_is_empty( clist ))

            clist->tail = new_element;


        clist->tail->next = clist->head;

    } else {

        new_element->next = element->next;

        element->next = new_element;

    }

    clist->size++;

    return 0;

}


4、删除

删除给定元素element之后的元素

异常情况:

链表为空

if( clist_is_full( clist ))

        return -1;


常规情况:

(1)如果element为NULL,或者element为尾节点,则删除头结点

        需要维护尾指针

        if ( element == NULL || clist_is_tail( element )){

            *data = clist->head->data;

            del_element = clist->head;

            if( clist_size( clist ) == 1 ){

                clist->tail = NULL;

                clist->head = NULL;

            } else {

                clist->head = clist->head->next;

            }

        } else {

(2)r如果删除的节点时尾节点,则需要维护尾指针

            *data = element->next->data;

            del_element = element->next;

            if( clist_is_tail(element->next )){

                clist->tail = element;

                clist->tail->next = clist->head;

            } else {

                element->next = element->next->next;

            }

        }

int clist_remove_next(CList_t *clist, CListElement_t *element, void **data )
{
    if( clist_is_empty( clist ))
        return -1;

    CListElement_t *del_element = NULL;
    if( element == NULL || clist_is_tail( element )){
        *data = clist->head->data;
        del_element = clist->head;
        if( clist_size( clist ) == 1 ){
            clist->head = NULL;
            clist->tail = NULL;
        } else {
            clist->head = clist->head->next;
            clist->tail = clist->head;
        }
    } else {
        *data = element->next->data;
        del_element = element->next;
        if( clist_is_tail( del_element) ){
            clist->tail = element;
            clist->tail->next = clist->head;
        } else {
            element->next = element->next->next;
        }
    }

    free( del_element );
    del_element = NULL;
    clist->size--;
    return 0;
}


int clist_remove_next(CList_t *clist, CListElement_t *element, void **data )

{

    if( clist_is_empty( clist ))

        return -1;


    CListElement_t *del_element = NULL;

    if( element == NULL || clist_is_tail( element )){

        *data = clist->head->data;

        del_element = clist->head;

        if( clist_size( clist ) == 1 ){

            clist->head = NULL;

            clist->tail = NULL;

        } else {

            clist->head = clist->head->next;

            clist->tail = clist->head;

        }

    } else {

        *data = element->next->data;

        del_element = element->next;

        if( clist_is_tail( del_element) ){

            clist->tail = element;

            clist->tail->next = clist->head;

        } else {

            element->next = element->next->next;

        }

    }


    free( del_element );

    del_element = NULL;

    clist->size--;

    return 0;

}



其他相关题目下面以超链接形式给出:

链表面试题合集


1、单链表基本操作

2、双链表基本操作

3、循环单链表基本操作

4、反转单链表

5、查找单链表倒数第K个节点

6、倒序打印链表

7、查找链表中间节点

8、删除链表第K个节点,平均时间复杂度为O(1)

9、判断链表是否有环

10、判断两个单链表是否相交

11、求相交链表的第一个相交节点

12、判断是否有环,并判定是6型环还是0型环

13、判断链表是否有环,并求环入口节点

14、合并两个有序单链表

15、给定链表中间某节点,不遍历链表,将带插入节点插入给定节点之前

16、删除链表重复元素



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值