POJ 2299 Ultra-QuickSort 归并排序、二叉排序树,求逆序数

题目链接: http://poj.org/problem?id=2299

题意就是求冒泡排序的交换次数,显然直接冒泡会超时,所以需要高效的方法求逆序数。

利用归并排序求解,内存和耗时都比较少, 但是有编码难度。。

二叉排序树,内存巨大,时间复杂度高,但是非常好写。。

 

归并排序版本:

 1 #include <stdio.h>
 2 #include <string.h>
 3 long long merge_arr(int arr[], int first, int mid, int last, int tmp[])
 4 {
 5     long long ret = 0;
 6     int i = first, j = mid+1, k = 0;
 7     while(i <= mid && j <= last)
 8     {
 9         if(arr[i] < arr[j])
10         {
11             tmp[k++] = arr[i++];
12             ret += j - mid - 1;
13         }
14         else tmp[k++] = arr[j++];
15     }
16     while(i <= mid)
17     {
18         tmp[k++] = arr[i++];
19         ret += last - mid;
20     }
21     while(j <= last)
22         tmp[k++] = arr[j++];
23     for(i = 0; i < k; i++)
24         arr[first+i] = tmp[i];
25     return ret;
26 }
27 
28 long long merge_sort(int arr[], int first, int last, int tmp[])
29 {
30     long long ret = 0;
31     if(first < last)
32     {
33         int mid = (first + last) / 2;
34         ret += merge_sort(arr, first, mid, tmp);
35         ret += merge_sort(arr, mid+1, last, tmp);
36         ret += merge_arr(arr, first, mid, last, tmp);
37     }
38     return ret;
39 }
40 
41 int n, num[500010], tmp[500010];
42 int main()
43 {
44     while(scanf("%d", &n) != EOF && n)
45     {
46         for(int i = 0; i < n; i++)
47             scanf("%d", &num[i]);
48         printf("%I64d\n", merge_sort(num, 0, n-1, tmp));
49     }
50     return 0;
51 }
View Code

 

二叉排序树版本:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 struct node
 5 {
 6     int data, cnt_right;
 7     struct node *left, *right;
 8 };
 9 
10 long long ans;
11 
12 void build(struct node *&p, int k)
13 {
14     if(p == NULL)
15     {
16         p = (struct node *)malloc(sizeof(struct node));
17         p->data = k;
18         p->cnt_right = 0;
19         p->left = p->right = NULL;
20     }
21     else if(p->data > k)
22     {
23         ans += p->cnt_right + 1;
24         build(p->left, k);
25     }
26     else
27     {
28         p->cnt_right++;
29         build(p->right, k);
30     }
31 }
32 
33 void del(struct node *p)
34 {
35     if(p == NULL)return;
36     del(p->left);
37     del(p->right);
38     free(p);
39 }
40 
41 int main()
42 {
43     int n, x;
44     while(scanf("%d", &n) != EOF && n)
45     {
46         ans = 0;
47         struct node *root = NULL;
48         while(n--)
49         {
50             scanf("%d", &x);
51             build(root, x);
52         }
53         del(root);
54         printf("%I64d\n", ans);
55     }
56     return 0;
57 }
View Code

 

posted @ 2013-08-12 16:40  Anti-Magic  阅读(281)  评论(0编辑  收藏  举报