雙向鏈表

  1. 意義:

    解決單鏈表的由於方向性引起的效率問題

    單鏈表有個缺陷,就是當數據量比較大的時候,當需要對已知節點做刪除,排序的等操作時,有一個問題,就是當需要從頭節點開始遍歷,往往效率較低,

    head==>1 ==> 2 ==>3 ==>4==5

    當我需要刪除3這個結點時,就得知道2這個結點的指針,但是隻能從頭指針開始遍歷,才能知道

    雙向鏈表的指針域,除了包含一個後繼指針外還包括一個前驅指針,這樣子,當擁有一個已知結點時,就不要從頭遍歷就可以知道這個指針的前驅指針,直接使用即可

     head<==> 1<==>2<==>3

    當已知3這個結點時,可以通過前驅指針,得到2這個結點的指針,然後可以做相應的處理

2.實現

2.1 數據結構

typedef struct node
{
    int data;                                           //數據域
    struct node *next;                                  //指針域
    struct node *prep;
}NODE_t;

next 爲後繼指針,prep爲前驅指針

2.2 創建

NODE_t *CreatNodeList()
{
    NODE_t *head = NULL;

    head = (NODE_t *)malloc(sizeof(NODE_t));
    if(!head)
        exit(-1);
        head->next = NULL; 
    head->prep = NULL;

    return head;
}

2.2 插入

int InsertNode(NODE_t *head,int data)
{
    NODE_t *cur = NULL;

    if(!head)
        exit(-1);

    cur = (NODE_t *)malloc(sizeof(NODE_t));
    if(!cur)
        exit(-1);

    cur->data = data;
    if(!head->next)
    {
        // 當只有頭節點時
        cur->next = head->next;
        cur->prep = head;
        head->next = cur;
    }
    else
    {
        // 當鏈表有節點元素時
        cur->next = head->next;
        head->next->prep = cur;
        cur->prep = head;
        head->next = cur;
    }

    return 0;
}

2.3 查找

NODE_t *findNode(NODE_t *head,int data)
{
    head = head->next;
    while(head)
    {
        if(head->data == data)
        {
            break;
        }
        head = head->next;
    }
    if(head == NULL)
    {
        printf("sorry,%d is not in the list\n",data);
    }

    return head;
}

2.4 刪除

int DeleteNodeOfList(NODE_t *head,NODE_t *pfind)
{

    if(pfind->next != NULL)
    {
        pfind->prep->next = pfind->next;
        pfind->next->prep = pfind->prep;
    }
    else
    {
        // 處理尾節點
        pfind->prep->next = NULL;
    }

    free(pfind);
    pfind = NULL;

    return 0;
}

2.5 修改

int UpdateNode(NODE_t *head,int olddata,int newdata)
{
    NODE_t *p = findNode(head,olddata);
    if(p)
    {
        p->data = newdata;
    }

    return 0;
}

2.6 排序

int sortList(NODE_t *head)
{
    int i = 0,j = 0;
    int listlen = 0;
    int tmpData = 0;
    NODE_t *p = NULL;

    // 使用冒泡排序,不動指針域,比較數據域,使用臨時變量,將有大小之別的節點的數據域交換
    // 得到鏈表長度,方便冒泡
    listlen = ListNodeLen(head);

    // 指到首節點
    p = head->next;
    for(i = 0;i < listlen-1;i++)
    {
        // 每一輪從頭開始
        p = head->next;
        for(j = 0;j<listlen - i-1;j++)
        {
            // 將小值排在前面
            if(p->data > p->next->data)
            {
                tmpData = p->data;
                p->data = p->next->data;
                p->next->data = tmpData;
            }
            p = p->next;
        }
    }

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