首页 > 编程知识 正文

求逆序数C语言,逆序数c语言编程

时间:2023-05-05 16:25:19 阅读:280574 作者:1470

线性代数之求逆序数

在线性代数中,经常要求序列的逆序数,即所有逆序之和。在一个排列中若较大的数字排在较小数字的左边,则成这两个数字构成一个逆序。求解过程用C语言描述如下:

#define N 5

int nixu(int a[])

{

int i,j;

int n=0;

for(i=0;i

for(j=i+1;j

if(a[i]>a[j])

n++;

return n;

}

void main()

{

int array[N]={5,4,3,2,1};

printf("nThe number of nixu is:%dn",nixu(array));

逆序数的计算

直接计数

计算一个排列的逆序数的直接方法是逐个枚举逆序,同时统计个数。例如在序列 { 2, 4, 3, 1 } 中,逆序依次为 (2,1), (4,3), (4,1), (3,1),因此该序列的逆序数为 4。下面这个 Visual Basic 6.0 编写的示例使用的就是直接计数的方法,函数 NiXushu 返回一个字符串的逆序数。

Private Function NiXuShu(ByVal l As String) As Long '逆序数计算

Dim i As Integer, j As Integer, c As Long

Dim n() As Integer

ReDim n(Len(l))

For i = 1 To Len(l)

n(i) = Val(Mid(l, i, 1))

For j = 1 To i - 1

If n(i) < n(j) Then

c = c + 1

End If

Next j

Next i

NiXuShu = c

End Function

归并排序

直接计数法虽然简单直观,但是其时间复杂度是 O(n^2)。一个更快(但稍复杂)的计算方法是在归并排序的同时计算逆序数。下面这个 C++ 编写的例子演示了计算方法。函数 mergeSort() 返回序列的逆序数。

int is1[n],is2[n];// is1为原数组,is2为临时数组,n为个人定义的长度

long mergeSort(int a,int b)// 下标,例如数组int is[5],全部排序的调用为mergeSort(0,4)

{

if(a

{

int mid=(a+b)/2;

long count=0;

count+=mergeSort(a,mid);

count+=mergeSort(mid+1,b);

count+=merge(a,mid,b);

return count;

}

return 0;

}

long merge(int low,int mid,int high)

{

int i=low,j=mid+1,k=low;

long count=0;

while(i<=mid&&j<=high)

if(is1[i]<=is1[j])// 此处为稳定排序的关键,不能用小于

is2[k++]=is1[i++];

else

{

is2[k++]=is1[j++];

count+=j-k;// 每当后段的数组元素提前时,记录提前的距离

}

w

hile(i<=mid)

is2[k++]=is1[i++];

while(j<=high)

is2[k++]=is1[j++];

for(i=low;i<=high;i++)// 写回原数组

is1[i]=is2[i];

return count;

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。