验证元素的唯一性(二重循环法和快排优化)

学校练习,简单的我就不放上来了,值得整理的,我保存一下

习题4

 

1.1.验证元素唯一性(二重循环)

 

1.1.1.算法描述

 

 验证元素唯一性,主要方法是:建立两重循环,进行校验每个元素和其他元素的

 

1.1.2.伪代码

 

UniqueElements(A[0..m-1])

//验证给定数组中的元素是否唯一

//输入:数组A[0..n-1]

//输出:如果A中元素全部唯一,返回true

//否则返回false

for i<- 0 to n-2 do

  for j<- i+1 to n-1 do

    if A[i]=a[j] return false

return true

 

1.1.3.算法实现

 

bool UniqueElements(int ele[],int len){

    for(int i=0;i<len-1;i++)

        for(int j=i+1;j<len;j++)

            if(ele[i]==ele[j]) return false;

    return true;

}

 

2.1.算法优化(quick sort 优化)

 

2.1.1.算法描述

 

使用quick sort排序算法进行优化,主要方法是:使用quick sort算法,进行元素排序,再取第一个值。

 

2.1.2验证元素唯一性(quick sort优化,伪代码)

 

UniqueElements(A[0..m-1]

//验证给定数组中元素是否唯一

//输入:数组A[0..n-1]

//输出:如果A中元素全部唯一,返回true

//否则返回false

qsort(A)

for i<-0 to len-1 do

  if A[i]=a[i+1] return false

return true

 

2.1.3改进算法实现

 

int cmp(const void *a,const void *b){

    return *(int*)b-*(int*)a;

}

bool UniqueElements(int ele[],int len){

    qsort(ele,len,sizeof(int),cmp);//这个qsort<stdlib.h>中自带的函数

    for(int i=0;i<len-1;i++)

        if(ele[i]==ele[i+1]) return false;

    return true;

}

 

3.1.快排算法(quick sort)

 

3.1.1.算法描述

 

快排算法,是对冒泡排序的一种改进,在其中,有着分冶的思想。我们取一个base,之后进行左右递归排序。在排序过程中,我们从右往左,找到刚好比base小的数字,将右值赋给左值,然后从左往右,找到刚好比base大的数字,将左值给右值,最后两值相等,我们将base给左值。

 

3.1.2.伪代码

 

   get_base(ele[0,m-1],left,right)

//获取划分的目标

//输入:一个元素,给定一个左值右值作为区间

//输出:返回划分的索引

base<-ele[left]

while left<right do

  while left<right and ele[right] >= base do

    right--

  end

  while left<right and ele[left] <= base do

    left++

  end

  ele[left]=base

end

return left;

 

quick_sort(ele[0,m-1],left,right)

//进行递归排序

//输入:一个元素,给定一个左值右值作为区间

if left<right do

  index<-getbase(ele,left,right)

  quick_sort(ele,left,right)

  quick_sort(ele,left,right)

end

 

 

3.1.3.实现

 int get_base(int ele[],int left,int right){

    int base=ele[left];

    while(left<right){

        while(left<right && ele[right]>=base) right--;

        ele[left]=ele[right];

        while(left<right && ele[right]<=base) left++;

        ele[right]=ele[left];

    }

    ele[left]=base;

    return left;

}

void quick_sort(int ele[],int left,int right){

    if(left<right){

        int index=get_base(ele,left,right);

        quick_sort(ele,0,index-1);

        quick_sort(ele,index+1,right);

    }

}

4.1.试验小结

 

在验证元素唯一性的时候,我们通常的做法是,进行两重循环,进行两两相比较,如果两两相同,则返回false,否则返回true,这种算法,时间复杂度为O(n^2),空间复杂度为O(1),所以我们想到了优化方案,使用快排,进行优化,之后依次进行遍历,即可得到。我们思考一下,在使用快排,我们的时间复杂度为O(nlogn),空间复杂度为O(1)。这个效率明显比之前的效率优化了太多。

 

快排算法中,我们可以使用C语言<stdlib.h>中自带的qsort函数,这个函数的原型如下,void qsort( void *buf, size_t num, size_t size, int (*compare)(const void *, const void *) );第一个buf,指的是你的数组,第二个参数size_t指的是一个无符号整型,为你的数组长度,第三个参数为你的数组元素大小,第四个参数为一个void指针,我们在C程序的学习中,知道了,void指针可以指向任意,也可以被任意所指向,所以,我们在定义比较函数cmp的时候,要注意,定义的是const void*的参数类型,之后再强转为元素指针类型,进行比较,这样做,能直接将快排算法,适用于整个C程序中任意排序。

 

在手写快速排序的时候,我们要注意一点,关于左右值的移动,应该先移动右值,赋值给左,然后再移动左,赋值给右,最后,返回左下标,作为划分点。

我们在了解划分的时候,不能够忘记一个思想,分冶的思想,这个思想在我们今后会经常能够用得到。

 

 

 

 

 

posted @ 2019-09-12 23:03  SteveYu  阅读(1658)  评论(0编辑  收藏  举报