您的位置:首页 > 理论基础 > 数据结构算法

【算法和数据结构】_6_线性结构_双链表

2013-06-03 22:53 686 查看
双链表与单链表的操作在很多地方都能用到。
循环链表的话,特殊应用也能用到,既可以用单链表实现循环列表,也能用双链表实现循环列表,用单链表节省存储空间,但是运算逻辑相对
双链表要复杂,这就是通常说的以时间换空间。 单对时间要求严格时候也可:以空间换时间。
循环列表的代码不打算在园子里贴出来了,实现过程中需要注意的是:虽然头节点在建立循环链表之后,任何一个都可以看成是头节点,但是
还是以创建时分配的第一个节点为宜,因为这样不会随时随地的找头节点,同时要注意的是:单节点的时候,需要自己指向自己以符合循环链表的
定义,这个容易忽略。
下面是双链表的代码,运行测试结果在代码下面:
/*
    本程序用来测试线性存储结构:链表
*/

#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
上面的代码没有写销毁双链表的代码。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: