zoukankan      html  css  js  c++  java
  • 【算法和数据结构】_6_线性结构_双链表

      双链表与单链表的操作在很多地方都能用到。

      循环链表的话,特殊应用也能用到,既可以用单链表实现循环列表,也能用双链表实现循环列表,用单链表节省存储空间,但是运算逻辑相对

    双链表要复杂,这就是通常说的以时间换空间。 单对时间要求严格时候也可:以空间换时间。

      循环列表的代码不打算在园子里贴出来了,实现过程中需要注意的是:虽然头节点在建立循环链表之后,任何一个都可以看成是头节点,但是

    还是以创建时分配的第一个节点为宜,因为这样不会随时随地的找头节点,同时要注意的是:单节点的时候,需要自己指向自己以符合循环链表的

    定义,这个容易忽略。

      下面是双链表的代码,运行测试结果在代码下面:

    /*
        本程序用来测试线性存储结构:链表
    */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    
    //**************************************************0
    //                定义双链表数据结构
    struct dbllink
    {
        char data;
        struct dbllink* preNode;
        struct dbllink* postNode;
    };
    
    typedef struct dbllink  DBLLINK;
    typedef DBLLINK* PDBLLINK;
    //**************************************************1
    
    
    
    //**************************************************0
    //                定义BOOL数据类型
    typedef enum {FALSE,TRUE}  BOOL ;
    //**************************************************1
    
    
    
    //**************************************************0
    //                定义申请存储空间宏
    #define  MALLOC(pNode,type,size) if(NULL==\
                (pNode=(type *)malloc(size*sizeof(type))))\
    {\
        return FALSE;\
    }
    //**************************************************1
    
    
    
    //**************************************************0
    //                定义申请表头宏
    #define  MALLOCH(pNode,type,size) if(NULL==\
                (pNode=(type *)malloc(size*sizeof(type))))\
    {\
        return NULL;\
    }else\
    {\
        pNode->data='\0';\
        pNode->preNode=NULL;\
        pNode->postNode=NULL;\
        return pNode;\
    }
    //**************************************************1
    
    
    
    
    PDBLLINK CreateDblLink(void);
    BOOL InitDblLink(PDBLLINK head,char element[]);
    void EchoDblLink(PDBLLINK head);
    PDBLLINK GetDblLinkEnd(PDBLLINK head);
    PDBLLINK GetDblLinkEnd(PDBLLINK head);
    BOOL AppendDblLink(PDBLLINK head,char element);
    PDBLLINK SearchDblLink(PDBLLINK head,char element);
    BOOL DenodeDblLink(PDBLLINK head,char element);
    BOOL InsertDblLink(PDBLLINK head,char elePos,char element);
    
    int main(int argc,char* argv[])
    {
        PDBLLINK head;
    
        head=CreateDblLink();
        if(head)
            puts("Yes.");
    
        if(InitDblLink(head,"hello world"))
            EchoDblLink(head);
        AppendDblLink(head,'A');
            EchoDblLink(head);
    
        if(SearchDblLink(head,'A'))
            puts("Yes");
        else
            puts("No");
    
        if(DenodeDblLink(head,'l'))
            EchoDblLink(head);
    
        if(InsertDblLink(head,'l','l'))
            EchoDblLink(head);
    
        getchar();
        getchar();
        return 0;
    }
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        创建双链表表头
    函数原型
        PDBLLINK CreateDblLink(void)
    函数参数:
        无
    返回值:
        创建成功返回表头指针,否则返回NULL
    异常
        无
    */
    PDBLLINK CreateDblLink(void)
    {
        PDBLLINK head;
    
        MALLOCH(head,DBLLINK,1);
    }
    //**************************************************1
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        初始化双链表
    函数原型:
        BOOL InitDblLink(PDBLLINK head,char element[])
    函数参数:
        PDBLLINK head: 链表头指针
        char element[]:初始化字符串
    返回值:
        如果初始化成功,返回TRUE,否则返回FALSE
    异常:
        无
    */
    BOOL InitDblLink(PDBLLINK head,char element[])
    {
        PDBLLINK temp,
                 end;
        int i;
    
        if(!head)
        {
            return FALSE;
        }
    
        end=head;
        for(i=0;element[i]!=0;i++)
        {
            MALLOC(temp,DBLLINK,1);
    
            temp->data='\0';
            temp->postNode =NULL;
            temp->preNode=end;
    
            end->data=element[i];
            end->postNode =temp;
            end=end->postNode ;
        }
        return TRUE;
    }
    
    //**************************************************1
    
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        打印链表
    函数原型:
        void EchoDblLink(PDBLLINK head)
    函数参数:
        PDBLLINK head:链表头指针
    返回值:
        无
    异常:
        无
    */
    void EchoDblLink(PDBLLINK head)
    {
        PDBLLINK temp;
    
        if(temp=head)
        {
            while(temp->postNode)
            {
                printf("%c",temp->data );
                temp=temp->postNode ;
            }
            putchar('\n');
            return ;
        }
        else
        {
            return ;
        }
    }
    //**************************************************1
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        获取最后的节点
    函数原型:
        PDBLLINK GetDblLinkEnd(PDBLLINK head)
    函数参数:
        PDBLLINK head:链表头指针
    返回值:
        如果获取成功,则返回链表尾节点指针,否则返回NULL
    异常:
        无
    */
    PDBLLINK GetDblLinkEnd(PDBLLINK head)
    {
        PDBLLINK temp;
        if(!head)
        {
            return NULL;
        }
        
        if(head->postNode)
        {
            temp=head;
            while(temp->postNode)
            {
                temp=temp->postNode;
            }
            return temp;
        }
        else
        {
            //仅有头指针
            return head;
        }
    }
    //**************************************************1
    
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        在链表尾增加节点
    函数原型:
        BOOL AppendDblLink(PDBLLINK head,char element)
    函数参数:
        PDBLLINK head:链表头指针
        char element: 要插入的字符
    返回值:
        如果增加成功,返回TRUE;否则返回FALSE
    异常:
        无
    */
    BOOL AppendDblLink(PDBLLINK head,char element)
    {
        PDBLLINK end,
                 NewNode;
    
        if(head)
        {
            end=GetDblLinkEnd(head);
    
            MALLOC(NewNode,DBLLINK,1);
    
            NewNode->data='\0';
            NewNode->postNode=NULL;
            NewNode->preNode =end;
    
            end->data=element;
            end->postNode=NewNode;
    
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    //**************************************************1
    
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        查找指定元素
    函数原型:
        PDBLLINK SearchDblLink(PDBLLINK head,char element)
    函数参数:
        PDBLLINK head:链表头指针
        char element: 要查找的字符
    返回值:
        如果增加成功,返回元素所在的节点指针;否则返回NULL
    异常:
        无
    */
    PDBLLINK SearchDblLink(PDBLLINK head,char element)
    {
        PDBLLINK temp;
    
        if(!head)
        {
            return NULL;
        }
        else
        {
            temp=head;
            while(temp->postNode)
            {
                if(temp->data ==element)
                    return temp;
                temp=temp->postNode ;
            }
            //如果遍历完毕,还没有返回,则查找失败
            return NULL;
        }
    }
    //**************************************************1
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        删除指定字符所在的节点
    函数原型:
        BOOL DenodeDblLink(PDBLLINK head,char element)
    函数参数:
        PDBLLINK head:链表头指针
        char element: 指定的字符
    返回值:
        如果删除成功,返回TRUE,否则返回FALSE;
    异常:
        无
    */
    BOOL DenodeDblLink(PDBLLINK head,char element)
    {
        PDBLLINK temp,
                 DeNode;
    
        if(NULL==head || head->postNode == NULL)
        {
            return FALSE;
        }
    
        temp=SearchDblLink(head,element);
    
        if(temp==head)
        {
            DeNode=head;
            head->postNode->preNode=NULL;
            head=head->postNode=NULL;
    
            DeNode->postNode=NULL;
            
            return TRUE;
        }
        else
        {
            temp->preNode->postNode =temp->postNode;
            temp->postNode->preNode=temp->preNode;
            free(temp);
            return TRUE;
        }
    }
    //**************************************************1
    
    
    
    
    
    //**************************************************0
    /*
    函数功能:
        增加节点
        1、如果指定的元素存在,则在指定元素之后增加
        2、如果指定的元素不存在,则在最后增加
    函数原型:
        BOOL InsertDblLink(PDBLLINK head,char element)
    函数参数:
        PDBLLINK head:链表头指针
        char elePos:指定的字符
        char element: 要插入的字符
    返回值:
        如果增加成功,返回TRUE,否则返回FALSE;
    异常:
        无
    */
    BOOL InsertDblLink(PDBLLINK head,char elePos,char element)
    {
        PDBLLINK temp,
                 NewNode;
    
        if(NULL==head )
        {
            return FALSE;
        }
    
        //如果仅有头节点,则必须插入到头节点之后
        if(head->postNode == NULL)
        {
            MALLOC(NewNode,DBLLINK,1);
    
            NewNode->data='\0';
            NewNode->postNode=NULL;
            NewNode->preNode=head;
    
            head->data=element;
            head->postNode=NewNode;
            return  TRUE;
        } 
    
        temp=SearchDblLink(head,element);
        MALLOC(NewNode,DBLLINK,1);
        
        NewNode->data =element;
        NewNode->postNode =temp->postNode;
        NewNode->preNode=temp;
        temp->postNode=NewNode;
        return TRUE;
    }
    //**************************************************1

      上面的代码没有写销毁双链表的代码。

  • 相关阅读:
    MVC动态添加文本框,后台使用FormCollection接收
    使用结构struct作为Dictionary<TKey,TValue>的键
    扩展方法的几个实例,扩展基本类型、接口、通过反射让扩展方法使用私有成员等
    使用Enum.TryParse()实现枚举的安全转换
    .NET泛型04,使用Lazy<T>实现延迟加载
    .NET泛型03,泛型类型的转换,协变和逆变
    .NET泛型02,泛型的使用
    dd、split、csplit命令
    seq命令
    uniq命令
  • 原文地址:https://www.cnblogs.com/volcanol/p/3034373.html
Copyright © 2011-2022 走看看