数据信息中的逆序对

逆序对

逆序对是指在一个元素序列中,按照一定的大小比较方法,序列中任两个元素大小顺序颠倒的组合。

A[1..n] 是一个包含 n 个不同数的数组 . 如果在 i<j 的情况下 , A[i]>A[j], (i,j) 就称为 A 中的一个逆序对 .

对于一个给定待排序序列 , 其中的逆序对的发现与还原正是排序所要解决的事情 . 排序过程中一般是先发现逆序对再将其还原 , 由于这些让我们联想到了排序性能提高的一些方法 .

1. 一次还原操作 , 使得多组逆序对还原 .

eg: 共有 21 对 共有 10

7,6,5,4,3,2,1--(1 7 互换 )-->1,6,5,4,3,2,7

一次还原处理了 11

2. 一次对换操作后 , 尽量不要或者少产生额外的逆序对

eg: 共有 16 对 共有 11

7,6,5,1,3,2,4--(4 7 互换 )-->4,6,5,1,3,2,7

一次还原处理了 5 , 另外又多产生了 (4,1) 一对

在我观察的比较类排序中 , 快速排序体现了 1 却缺失了 2; 合并排序恰恰相反体现了 2 却缺失了 1.

关于逆序对的相关统计算法代码参见

/* Copyright (C) 2000-2007 Wang Pengcheng <wpc0000@163.com>
 * Licensed to the Wang Pengcheng under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The LGPL licenses this file to You under the GNU Lesser General Public
 * Licence, Version 2.0  (the "License"); you may not use this file except in
 * compliance with the License.  You may obtain a copy of the License at
 *
 *     http://www.gnu.org/licenses/lgpl.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package mypackage.algorithm.unit02;

public class Inversion ...{
    
    private static int tot;
    
    /** *//**
     *InsertionSort
     *The time limit of this sort is O(n^2)
     *<strong>O(n^2)</strong>
     *@param  element will be sorted
     */
    private static <Type extends Comparable> void insertionSort(Type element[])...{
        for(int j=1;j<element.length;j++)...{
            Type    key    =    element[j];
            int i    =    j-1;
            
            while( (i>=0)&&(element[i].compareTo(key)>0))...{
                element[i+1]    =    element[i];
                tot++;
                i--;
            }
            element[i+1]    =    key;
        }
    }
    /** *//**
     *Merge used in the mergeSort
     *<strong>O(n)</strong>
     *@param element Type[] the elements to be merged
     *@param p int the begin of the  first elements
     *@param q int the end of the first elements
     *@param r int the end of the second elements
     */
    private static <Type extends Comparable> void merge(Type element[],int p,int q,int r)...{
        int nl    =    q-p+1;
        int nr    =    r-q;
        
        Type[] lElement,rElement;
        lElement    =    (Type[])java.lang.reflect.Array.newInstance(element.getClass().getComponentType(),nl);
        rElement    =    (Type[])java.lang.reflect.Array.newInstance(element.getClass().getComponentType(),nr);
                
        for(int i=0;i<nl;i++)...{
            lElement[i]    =    element[p+i];
        }
        for(int i=0;i<nr;i++)...{
            rElement[i]    =    element[q+i+1];
        }
        
        int i=0,j=0;
        int k    =    p;
        while((i<nl)&&(j<nr))...{
            if(lElement[i].compareTo(rElement[j])<=0)...{
                element[k]    =    lElement[i];
                i++;
            }else...{
                element[k]    =    rElement[j];
                j++;
                tot+=nl-i;
            }
            k++;
        }
        
        while(i<nl)...{
            element[k]    =    lElement[i];
            i++;
            k++;
        }
        while(j<nr)...{
            element[k]    =    rElement[j];
            j++;
            k++;
        }
    }
    
    /** *//**
     *mergeSort
     *Sort the elements by the compareTo method
     *<strong>O(nlgn)</strong>
     *@param  element Type[] that will be sorted
     *@param p the begin of the list will be sorted
     *@param r the end of the list will be sorted
     */
    private static <Type extends Comparable> void mergeSort(Type element[],int p,int r)...{
        if(p<r)...{
            int q    =    (p+r)/2;
            mergeSort(element,p,q);
            mergeSort(element,q+1,r);
            merge(element,p,q,r);
        }
    }
    private static <Type extends Comparable> void mergeSort(Type element[])...{
        mergeSort(element,0,element.length-1);
    }
    
    /** *//**
     * Count the inversion number by O(nlgn)
     * @param <Type> inversion number type
     * @param element inversion number list
     * @return count number of inversion
     */
    public static <Type extends Comparable>  int countMerge(Type element[])...{
        tot=0;
        mergeSort(element.clone());
        return tot;
    }

    /** *//**
     * Count the inversion number by O(n^2)
     * @param <Type> inversion number type
     * @param element inversion number list
     * @return count number of inversion
     */
    public static <Type extends Comparable> int countInsertion(Type element[])...{
        tot=0;
        insertionSort(element.clone());
        return tot;
    }
    /** *//**
     * @param args
     */
    public static void main(String[] args) ...{
        Integer[] a = ...{4,6,5,1,3,2,7};
        System.out.println(Inversion.countMerge(a));
    }

}
 

最后让我们牢记 :

摘《李开复:算法的力量算法并不局限于计算机和网络

举一个计算机领域外的例子:在高能物理研究方面,很多实验每秒钟都能几个 TB 的 数据量。但因为处理能力和存储能力的不足,科学家不得不把绝大部分未经处理 的数据丢弃掉。可大家要知道,新元素的信息很有可能就藏在我们来不及处理的数据里面。同样的,在其他任何领域里,算法可以改变人类的生活。例如人类基因的 研究,就可能因为算法而发明新的医疗方式。在国家安全领域,有效的算法可能避免下一个 911 的发生。在气象方面,算法可以更好地预测未来天灾的发生,以拯 救生命。

所以,如果你把计算机的发展放到应用和数据飞速增长的大环境下,你一定会发现;算法的重要性不是在日益减小,而是在日益加强。

谢谢大家。

参考书籍

Inroduction to Algorithms Thomas H.Cormen,Charles E.Leiserson,Ronald L. Rivest,Clifford Stein. 机械工业出版社

《数据结构》殷人昆,陶永雷,谢若阳,盛绚华 清华大学出版社

《算法艺术与信息学竞赛》刘汝佳,黄亮 清华大学出版社

《李开复:算法的力量》 http://www.ieee.org.cn/dispbbs.asp?boardID=60&ID=31651

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值