改造一個雙向循環鏈表,使右鏈域保持原來的順序,而左鏈域從小到大順序排列。

   // 這道題的算法是我自己編寫而來的,我也是一名學生,如果有什麼更好的方法,我們可以相互交流。

     在我的算法中,我使用了一個宏定義MaxNum 表示最大的數,實現了對左鏈域從小到大排列。實現從大到小排列只需要把MaxNum改成Minmun即可。也是本算法最大的一個優點。好,話不多說,現在我來說一下自己的思想。

  1. 先將所有結點的左指針全部清空。
  2. 定義3個指針,p(查找指針),q(定位最小元素指針),s(左鏈域中的尾指針);
  3. 初始化:p = head->rlink; q = NULL; s = head;    //head爲表頭結點
  4. 一次循環找到最小元素並用q定位;
  5. 找到q之後,做尾插法的即可。值得注意的是q的左指針要指會表頭。
  6. 一直循環,直到所有的結點的左鏈域都不爲空。    //很關鍵,之前置空操作,也是爲了判斷循環什麼時候結束。

    這樣這道題就做出來了,非常值得去總結。如果有其它問題歡迎留言。

 

僞代碼如下:

 int LevelUp(DRLNode*& head)     
{
    int e;                         //記錄未被左鏈域連接的結點中的最小值
    DRLNode* p, * q, * s;         //p爲查找指針 q爲定位指針 s爲左鏈域的尾指針
    p = head->next; q = NULL;    
    s = head;                     //初始化
    while (p != head)
    {
        p->prior = NULL;
        p = p->next;
    }                             //先將所有除頭結點的結點的左指針清空
    while (true)                     //將結點左鏈域從大到小排列
    {
        e = MaxNum;                 //初始化 MaxNum宏定義爲一個很大的數
        p = head->next;
        while (p != head)
        {
            if (p->prior != NULL) //如果p左指針不爲空 說明已經在左鏈域中 不參與比較 直接向後移動
                p = p->next;
            else if (p->data < e) //判斷結點是否爲最小值結點
            {    
                e = p->data; 
                q = p;              //記錄最小值結點
                p = p->next;
            }
            else                  //不是最小值向後移動
                p = p->next;
        }                          
        s->prior = q;
        q->prior = head;
        s = q;                      //這三行爲關鍵連接代碼,將該結點連接到左鏈域
        if (e == MaxNum)          //如果e的值沒有變化說明結點都連接在左鏈域
            return OK;
    }
}

 

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