自顶向下归并排序的应用——链表的随机化

     在对一个链表进行随机化时,可以借鉴自顶向下归并排序的思路,先将链表划分为左右两个子链表,分别进行随机化,然后再归并两个子链表,并在归并过程中进行随机化,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// *pHead指向链表的首节点(不是头结点)
void RandomizeLinkedList(Link * pHead)
{
    int length = CountNodes(* pHead);
    Randomize(pHead,length);
 
    Link tail = * pHead;
     
    for(int i = 1;i < length;i++)
    {
        tail = tail->next;
    }
     
    tail->next = NULL;
}
 
// 随机化首节点由*pHead指向,长度为length的链表,随机化完成后*pHead指向链表新的首节点。该函数类似于自顶向下的归并排序
Randomize(Link * pHead,int length)
{
    if(length == 1)
    {
        return;
    }
 
    int lengthOfLeftSublist = length / 2;
    int lengthOfRightSublist = length - lengthOfLeftSublist;
     
    Link headOfRightSublist =  * pHead;
    for(int i = 0;i < countOfLeftSublist;i++)
    {
        headOfRightSublist = headOfRightSublist->next;
    }
 
    Randomize(pHead,lengthOfLeftSublist);
    Randomize(&headOfRightSublist,lengthOfRightSublist);
 
    Merge(pHead,length,lengthOfLeftSublist,headOfRightSublist);
}
 
// 链表的首结点由*pHead指向,长度为length,对其已经完成随机化的左右子链表进行归并,归并完成后*pHead指向链表新的首节点
void Merge(Link * pHead,int length,int lengthOfLeftSublist,Link headOfRightSublist)
{
    Link headOfLeftSublist = * pHead;
 
    if(GetProbability((double)lengthOfLeftSublist/length)))
    {
        headOfLeftSublist = headOfLeftSublist->next;
        lengthOfLeftSublist--;
    }
    else
    {
        * pHead = headOfRightSublist;
        headOfRightSublist = headOfRightSublist->next;
    }
 
    length--;
 
    Link tail = * pHead;
     
    while(lengthOfLeftSublist > 0)
    {
        if(GetProbability((double)lengthOfLeftSublist/length)))
        {
            tail->next = headOfLeftSublist;
            headOfLeftSublist = headOfLeftSublist->next;
            lengthOfLeftSublist--;
        }
        else
        {
            tail->next = headOfRightSublist;
            headOfRightSublist = headOfRightSublist->next;
        }
 
        length--;
        tail = tail->next;
    }
 
    if(length > 0)
    {
        tail->next = headOfRightSublist;
    }
}
 
bool GetProbability(double probability)
{
    return  rand() / RAND_MAX < probability;
}

  

 

posted @   姚来飞  阅读(261)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示