zoukankan      html  css  js  c++  java
  • 链表

    链表可以有多种形式。

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

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

    插入和删除时间复杂度为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
  • 相关阅读:
    使用集合组织相关数据
    深入类的方法
    深入C#数据类型
    上机练习1 更新会员积分
    魔兽争霸登录
    jQuery
    打卡系统
    [工具]kalilinux2016.2 更新后
    [技术分享]借用UAC完成的提权思路分享
    [技术分享]利用MSBuild制作msf免杀的后门
  • 原文地址:https://www.cnblogs.com/yanxin880526/p/7469485.html
Copyright © 2011-2022 走看看