C語言雙鏈表插入

有序雙鏈表

typedef struct NODE {
    struct NODE* fwd;
    struct NODE* bwd;
    int          value;
}Node;

fwd指向下一個節點,bwd指向前一個節點。

可能的情況:

1)新值插入到鏈表中間位置;

2)新值插入到鏈表的起始位置;

3)新值插入到鏈表的結束位置;

4)新值插入到鏈表的起始位置,又插入到鏈表的結束位置(原鏈表爲空)。

/*
**把一個值插入到一個雙鏈表,rootp是一個指向根節點的指針,
**value是要插入的新值
**返回值:如果要插入的值已經存在,返回0
**如果內存不足導致無法插入,返回-1,如果插入成功,返回1。
*/

#include <stdlib.h>
#include <stdio.h>
#include "doubly_linked_list_node.h"

int
dll_insert(Node *rootp, int value)
{
    Node *this;
    Node *next;
    Node *newnode;

    /*
    **查看value是否已經存在於鏈表中,如果是就返回
    **否則,創建一個新節點(讓newnode指向它)
    **“this”將指向應該在新節點之前的那個節點
    **“next”蔣指向應該在新節點之後的那個節點
    */
    for(this = rootp; (next = this->fwd) != NULL; this = next){
        if(next->value == value)
            return 0;
        if(next->value > value)
            break;
    }
    newnode = (Node*)malloc(sizeof(Node));
    if(newnode = NULL)
        return -1;
    newnode->value = value;

/*
**把新節點添加到鏈表中
*/
if(next != NULL){
/*
**情況1/2:不位於鏈表尾部
*/
    if(this != rootp){        /*情況1:不在起始位置*/
        newnode->bwd = this;
        newnode->fwd = next;
        this->fwd = newnode;
        next->bwd = newnode;
    }
    else{                    /*情況2:位於鏈表起始位置*/
        rootp->fwd = newnode;
        next->bwd = newnode;
        newnode->bwd = NULL;
        newnode->fwd = next;
    }
}
else{
/*
**情況3/4:位於鏈表的尾部
*/
    if(this != NULL){        /*情況3:位於結束位置,不在起始位置*/
        newnode->fwd = NULL;
        newnode->bwd = this;
        this->fwd = newnode;
        rootp->bwd = newnode;
    }
    else{                    /*情況4:位於鏈表起始位置也位於結束位置*/
        newnode->fwd = NULL;
        newnode->bwd = NULL;
        rootp->fwd = newnode;
        rootp->bwd = newnode;
    
}
    
return 1;

}

技巧一:statement factoring:

各個嵌套的if語句內存在大量相似之處,所以把他們提煉出來



/*
**把新節點添加到鏈表中
*/
if(next != NULL){
/*
**情況1/2:不位於鏈表尾部
*/
    newnode->fwd = next;
    if(this != rootp){        /*情況1:不在起始位置*/
        newnode->bwd = this;        
        this->fwd = newnode;
    }
    else{                    /*情況2:位於鏈表起始位置*/
        rootp->fwd = newnode;   
        newnode->bwd = NULL;  
    }
    next->bwd = newnode;
}
else{
/*
**情況3/4:位於鏈表的尾部
*/
    newnode->fwd = NULL;
    if(this != NULL){        /*情況3:位於結束位置,不在起始位置*/        
        newnode->bwd = this;
        this->fwd = newnode;
    }
    else{                    /*情況4:位於鏈表起始位置也位於結束位置*/
        newnode->bwd = NULL;
        rootp->fwd = newnode; 
    }
    rootp->bwd = newnode;       
    
}
    
return 1;

}

技巧二:邏輯提煉

情況3/4的第一條,this=NULL的時候賦值給newnode->bwd=NULL相當於newnode->bwd=this,

/*
**把新節點添加到鏈表中
*/

    newnode->fwd = next;
    if(this != rootp){        /*情況1:不在起始位置*/
        newnode->bwd = this;        
        this->fwd = newnode;
    }
    else{                    /*情況2:位於鏈表起始位置*/
        rootp->fwd = newnode;   
        newnode->bwd = NULL;  
    }
    
    if(next != NULL)
        next->bwd = NULL;
    else
        rootp->bwd = newnode;


    

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章