改造一个双向循环链表,使右链域保持原来的顺序,而左链域从小到大顺序排列。

   // 这道题的算法是我自己编写而来的,我也是一名学生,如果有什么更好的方法,我们可以相互交流。

     在我的算法中,我使用了一个宏定义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;
    }
}

 

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