您的位置:首页 > 其它

归并排序&&数组中逆序对问题

2012-08-09 15:30 309 查看
题目:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。例如在数组{7,5,6,4}中,一共存在5个逆序对,分别是{7,5}、{7,6}、{7,4}、{5,4}、{6,4}


解析:我们可以利用归并排序的过程中统计出逆序对的个数,算法时间复杂度为O(nlogn)

归并排序实现代码:

#include <iostream>
using namespace std;

void Merge(int arr[], int temp_arr[], int begin, int middle, int end)
{
for(int i = begin; i <= end; i++)// 将arr中元素保存至副本
{
temp_arr[i] = arr[i];
}

int left = begin;
int right = middle+1;
int temp_pos = begin;

while(left <= middle && right <= end)
{
if(temp_arr[left] <= temp_arr[right])
{
arr[temp_pos++] = temp_arr[left++];
}
else
{
arr[temp_pos++] = temp_arr[right++];
}
}
while(left <= middle)
{
arr[temp_pos++] = temp_arr[left++];
}
while(right <= end)
{
arr[temp_pos++] = temp_arr[right++];
}
}
void MergeSort(int arr[], int temp_arr[], int begin, int end)
{
if(begin < end) //至少两个元素
{
int middle = (begin + end)/2;
MergeSort(arr, temp_arr, begin, middle);
MergeSort(arr, temp_arr, middle+1, end);
Merge(arr, temp_arr, begin, middle,end);
}
}
void MergeSort(int arr[], int length)
{
if(NULL == arr || length <= 0)
return;

int *temp_arr = new int[length]; // 临时数组,保存arr副本
if(NULL == temp_arr)
return;   //  这里不单单应是直接return就可以了,还要让用户知道错误

MergeSort(arr, temp_arr, 0, length - 1);

delete[] temp_arr;

}
int main()
{
int a[] = {2, 3, 4, 56, 7, 8, 9, 5, 4};
MergeSort(a, 9);

for(int i = 0; i != 9; i++)
cout << a[i] <<endl;
system("pause");
}


数组中逆序对问题实现代码

#include <iostream>
using namespace std;

int reverse_pairs_count = 0;

void Merge(int arr[], int temp_arr[], int begin, int middle, int end)
{
for(int i = begin; i <= end; i++)// 将arr中元素保存至副本
{
temp_arr[i] = arr[i];
}

int left = begin;
int right = middle+1;
int temp_pos = begin;

while(left <= middle && right <= end)
{
if(temp_arr[left] <= temp_arr[right])
{
arr[temp_pos++] = temp_arr[left++];
}
else
{
//temp_arr[left] > temp_arr[right], 表示出现了逆序对,此时由于
//temp_arr[left..middle]是已经有序了,那么temp_arr[i+1], temp_arr[i+2], ... temp_arr[middle]都是大于temp[right]的,
//都可以和temp[right]组成逆序对,因此reverse_pairs_count +=middle - left + 1
reverse_pairs_count += middle - left + 1;
arr[temp_pos++] = temp_arr[right++];
}
}
while(left <= middle)
{
arr[temp_pos++] = temp_arr[left++];
}
while(right <= end)
{
arr[temp_pos++] = temp_arr[right++];
}
}
void MergeSort(int arr[], int temp_arr[], int begin, int end)
{
if(begin < end) //至少两个元素
{
int middle = (begin + end)/2;
MergeSort(arr, temp_arr, begin, middle);
MergeSort(arr, temp_arr, middle+1, end);
Merge(arr, temp_arr, begin, middle,end);
}
}
void MergeSort(int arr[], int length)
{
if(NULL == arr || length <= 0)
return;

int *temp_arr = new int[length]; // 临时数组,保存arr副本
if(NULL == temp_arr)
return;   //  这里不单单应是直接return就可以了,还要让用户知道错误

MergeSort(arr, temp_arr, 0, length - 1);

delete[] temp_arr;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: