zoukankan      html  css  js  c++  java
  • 双向链表基本操作以及优化可能

    面试时面试官要求手写双向链表的 删除操作,当时没有考虑到边界条件,导致被刷;
    现在 列举下代码以及优化,作为事后反思:

    C 版本:

    双向链表的结构定义

    typedefstruct doubleLink
    {
    int data;
    struct doubleLink *prior;
    struct doubleLink *suffix;
    }DOUBLE_LINK;
    

      

    创建一个双向链表

    /*创建一个双链表*/
    DOUBLE_LINK *createDoubleLink()
    {
    DOUBLE_LINK *head = NULL;
    head =(DOUBLE_LINK*)malloc(sizeof*head);
    head->prior = NULL;
    head->suffix = NULL;
    return head;
    }
    

      

    插入函数

    /*插入节点*/
    bool insertNode(DOUBLE_LINK*head,int data)
    {
    if(head == NULL)
    returnfalse;
    DOUBLE_LINK *currNodep = NULL;
    DOUBLE_LINK *nextp = NULL;
    DOUBLE_LINK *newNodep = NULL;
    for(currNodep = head;(nextp = currNodep->suffix)!= NULL; currNodep = nextp)
    {
    if(nextp->data == data)
    returnfalse;
    if(nextp->data > data)
    break;
    }
    newNodep =(DOUBLE_LINK*)malloc(sizeof*newNodep);
    if(newNodep == NULL)
    returnfalse;
    newNodep->data = data;
    #if 1
    /*需要插入双向链表时,遍历到需要插入的位置,开始对待插入的节点,前驱指针和后驱指针赋值,
    后驱指针固定指向下一个节点指针,前驱需要区分 前指针是否是 头节点。
    再对 当前节点的前驱指针赋值,需要区分待插入的点是不是 尾节点*/
    //1.当前节点的后驱指针
    currNodep->suffix = newNodep;
    //2.新节点的前驱指针
    if(currNodep == head)
    newNodep->prior = NULL;
    else
    newNodep->prior = currNodep;
    //3.新节点的后驱指针
    newNodep->suffix = nextp;
    //4.下一个节点的前驱指针
    if(nextp == NULL)//到了尾节点处,则将头节点的前驱指向该尾节点,这是双向链表的结构精髓所在
    head->prior = newNodep;
    else
    nextp->prior = newNodep;
    #else
    if(nextp != NULL)
    {
    //one not in the tail
    newNodep->suffix = nextp;
    currNodep->suffix = newNodep;
    if(currNodep != head)// not the head
    {
    newNodep->prior = currNodep;
    }
    else// currnode is head
    {
    newNodep->prior = NULL;
    }
    nextp->prior = newNodep;
    }
    else
    {
    //in the tail
    currNodep->suffix = newNodep;
    if(currNodep != head)//not the head
    {
    newNodep->prior = currNodep;
    }
    else//is the head
    {
    head->prior = newNodep;
    newNodep->prior = NULL;
    }
    newNodep->suffix = NULL;
    }
    #endif
    returntrue;
    }
    

      

    删除某个节点

    /*删除某个节点*/
    bool deleteNode(DOUBLE_LINK *head, DOUBLE_LINK *item)
    {
    _ASSERT(head != NULL);
    _ASSERT(item != NULL);
    DOUBLE_LINK *currentNodep = NULL;
    DOUBLE_LINK *nextp = NULL;
    for(currentNodep = head;(nextp = currentNodep->suffix)!= NULL; currentNodep = nextp)
    {
    if(nextp == item)
    {
    /*当前节点为头结点时,这一点很重要*/
    if(currentNodep == head)// the head
    {
    currentNodep->prior = NULL;
    currentNodep->suffix = nextp->suffix;
    free(nextp);
    nextp = NULL;
    break;
    }
    //最后一个节点时
    elseif(nextp->suffix == NULL)// the tail
    {
    currentNodep->suffix = NULL;
    free(nextp);
    nextp = NULL;
    break;
    }
    else// the mid
    {
    DOUBLE_LINK *tmp = nextp->suffix;
    currentNodep->suffix = nextp->suffix;
    nextp->prior = currentNodep;
    free(nextp);
    nextp = tmp;
    }
    }
    }
    returntrue;
    }
    

      

    删除节点函数优化

    bool deleteNode_opt(DOUBLE_LINK *head, DOUBLE_LINK *item)
    {
    _ASSERT(head != NULL);
    _ASSERT(item != NULL);
    //要删除第一个节点
    if(item == head->suffix)
    {
    head->suffix = item->suffix;
    item->suffix->prior = NULL;
    }
    //要删除最后一个节点
    elseif(item == head->prior)
    {
    head->prior = item->prior;
    item->prior->suffix = NULL;
    }
    else
    {
    item->prior->suffix = item->suffix;
    item->suffix->prior = item->prior;
    }
    free(item);
    item = NULL;
    returntrue;
    }
    

      

    打印函数

    void printAllNode(DOUBLE_LINK *head)
    {
    _ASSERT(head != NULL);
    DOUBLE_LINK *currentNodep = NULL;
    DOUBLE_LINK *nextNodep = NULL;
    std::cout <<"Node data is: ";
    for(currentNodep = head;(nextNodep = currentNodep->suffix)!= NULL; currentNodep = nextNodep)
    {
    std::cout << nextNodep->data<<" ";
    }
    std::cout << std::endl;
    }
    

      

  • 相关阅读:
    IDETalk
    servlet概述
    过滤器(Filter)
    ieda常用快捷键
    UUID
    JRebel 7.0.10 for intellij IDEA 2017.1
    BP神经网络(手写数字识别)
    遗传算法解决TSP问题
    [CODEVS1258]关路灯
    [NOIP2007]统计数字
  • 原文地址:https://www.cnblogs.com/Stultz-Lee/p/6847475.html
Copyright © 2011-2022 走看看