学校练习,简单的我就不放上来了,值得整理的,我保存一下
习题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程序中任意排序。
在手写快速排序的时候,我们要注意一点,关于左右值的移动,应该先移动右值,赋值给左,然后再移动左,赋值给右,最后,返回左下标,作为划分点。
我们在了解划分的时候,不能够忘记一个思想,分冶的思想,这个思想在我们今后会经常能够用得到。