链表

链表可以有多种形式。

它可以是单链接的或双链接的,可以是已排序的或未排序的,可以是循环的或非循环的。

下面我们实现双链接、未排序、非循环,带头节点指针的链表。示意图如下:

插入和删除时间复杂度为O(1),查找最坏时间复杂度为O(n). 

代码如下:

/*
 * 双链接、未排序、非循环链表。带头指针
*/
#include <stdio.h>
#include <stdlib.h>

typedef struct object {
    int key;
    struct object *next,*prev;
}object_s;

object_s *list_search(object_s * l, int key);
void list_insert(object_s **l, object_s *intx);
void list_delete(object_s **l, object_s *intx);

int main(void)
{
    object_s * l=NULL; // 初始化一个链表
    object_s x;
    x.key=5;
    list_insert(&l,&x);
    list_delete(&l,&x);
    
    if(list_search(l,5)==NULL) {
        printf("the link hasn't key 5.
");
        exit(1);
    } else {
        printf("find the value 5
");
    }
    return 0;
}

// 查找链表l中第一个关键字为key的元素,并返回指向该元素的指针。
object_s *list_search(object_s * l, int key)
{
    object_s * pobj;
    pobj = l;
    while(pobj!=NULL && pobj->key!=key)
        pobj = pobj->next;
    return pobj;
}

// 给定设置好关键字key的元素intx,将intx插入链表的前端
void list_insert(object_s **l, object_s *intx)
{
    intx->next = *l;
    intx->prev = NULL;
    if(*l != NULL)
        (*l)->prev=intx;
    *l = intx;
}

// 将元素intx从链表l中移除
void list_delete(object_s **l, object_s *intx)
{
    if(intx == *l)
        *l = intx->next;
    else
        intx->prev->next = intx->next;
    
    if(intx->next != NULL)
        intx->next->prev = intx->prev;
}
list.c

接下来实现双链表、非排序、循环,带哨兵的链表。哨兵是一个哑对象,其作用是简化边界条件的处理。

示意图如下所示:

插入和删除时间复杂度为O(1),查找最坏时间复杂度为O(n). 

代码如下:

/*
 * 双链接、未排序、循环链表。
 * 使用哨兵,可以忽略表头和表尾处的边界条件。
*/
#include <stdio.h>
#include <stdlib.h>

typedef struct object {
    int key;
    struct object *next,*prev;
}object_s;

typedef struct list {
    object_s nil;
}list_s;

object_s *list_search(list_s *list, int key);
void list_insert(list_s *list, object_s *intx);
void list_delete(list_s *list, object_s *intx);

int main(void)
{
    list_s lt;
    object_s intx;

    lt.nil.key=0;
    lt.nil.next = &(lt.nil);
    lt.nil.prev = &(lt.nil);
    
    intx.key=7;

    list_insert(&lt, &intx);

    if(list_search(&lt,7)==&(lt.nil)) {
        printf("the link hasn't key 7.
");
        exit(1);
    } else {
        printf("find the value 7
");
    }
    
    list_delete(&lt,&intx);
    
    if(list_search(&lt,7)==&(lt.nil)) {
        printf("the link hasn't key 7.
");
        exit(1);
    } else {
        printf("find the value 7
");
    }
    
    return 0;
}

// 查找链表l中第一个关键字为key的元素,并返回指向该元素的指针。
object_s *list_search(list_s *list, int key)
{
    object_s * pobj;
    
    pobj = (list->nil).next;
    while(pobj!=&(list->nil) && pobj->key!=key)
        pobj = pobj->next;
    return pobj;
}

// 给定设置好关键字key的元素intx,将intx插入链表的前端
void list_insert(list_s *list, object_s *intx)
{
    intx->next = (list->nil).next;
    intx->prev = &(list->nil);
    (list->nil).next->prev = intx;
    (list->nil).next = intx;
}

// 将元素intx从链表l中移除
void list_delete(list_s *list, object_s *intx)
{
    intx->prev->next = intx->next;
    intx->next->prev = intx->prev;
}
View Code
原文地址:https://www.cnblogs.com/yanxin880526/p/7469485.html