数组中相差最小的两个元素(最接近数)的差
伪代码与C++描述
伪代码描述
1 利用快速排序 让数组有序化
quicksort(*a,left,right){
i=left j=right // 两个工作指针
if(i<j){ // 直至子表只有一元素(左=右) 排序结束
pivot=a[i] //将最左边的字作为比较的关键字
while(i != j){ //直至左右两个指针遇到 这一趟排序结束
while(a[j]>=pivotkey) j-- //先从右边向左找 直至找到一个比它小的数a[i]
while(a[i]<=pivotkey) i++ //再从左边向右找 直到找到一个比它大的a[j]
exchange a[i] <--> a[j]
}
exchange a[left] <--> a[i]
}
quicksort(*a,left,i-1)
quicksort(*a,i+1,right)
//递归调用quicksort 将当前区间以枢轴为界 一分为二
}
2 循环遍历 两两相邻的数的差值 不断更新dvalue
different(){
for(i=2;i<=n;i++) { //从数组第二个数开始n-1次遍历
elem=a[i]-a[i-1] //不断获得新的差值
dvalue=elem //不断获得更小的差值 用dvalue储存
}
}
C++ 描述
1.快排的实现
void quicksort(int *a,int left, int right) {
int i, j, t, pivotkey;
if (left > right) {
return;
}
pivotkey = a[left];//每次将 区间 最左边的数字 作为比较的关键字pivotkey
i = left;
j = right;
while (i != j) {
while (a[j] >= pivotkey && i < j) { //先从右边找
j--;
}
while (a[i] <= pivotkey && i < j) {
i++;
}
//与之前数据结构课本上的算法有一点区别是 找到左右两边不合法的数据 直接交换 这样不容易出错 也更容易理解
if (i < j) {
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
a[left] = a[i];
a[i] = pivotkey;
//以上两句就是将 最左边的数与当前枢轴位置上的数交换 当前a[i]位置上的数字是一定符合小于枢轴的 这是因为每次都从右边往左找的原因
//递归调用
quicksort(a,left, i - 1);
quicksort(a,i + 1, right);
}
- 完成排序任务
2.遍历寻找最小差值
void differentvalue(int *a,int n) {
int dvalue = 100001;
for (int i = 2; i <= n; i++) {
int elem = a[i] - a[i - 1];//cout << elem << endl;
if (elem < dvalue) {
dvalue = elem;//更新最小差 different value
}
}
cout << "最小值是 :" << dvalue << endl;
}
- 找到最小差
3.主函数
int main() {
int i, j, t;
int a[101], n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
quicksort(a,1, n);
differentvalue(a,n);
system("pause");
return 0;
}
快排与冒泡的比较:
项目 | 时间复杂度 |
---|---|
快速排序1 | O(nlog2n) |
冒泡排序 | O(n2) |
复杂度分析
先快排O(nlog2n) + 一个for循环O(n)
所以算法时间复杂度为 O(nlog2n)
快速排序是由冒泡排序改进而成,由只对相邻两个个记录进行比较进而交换一次只能消除一个逆序>>改进为>>通过两个不相邻的记录的一次交换,消除多个逆序,则会大大加快排序的速度。 快速排序:在待排序的n个元素中任取一个元素(通常取第一个元素left)作为枢轴(关键字),经过一趟排序,将待排序元素分成两个子表,最后将枢轴放在分界处的位置(故一趟排序可确定 当前枢轴元素的最终位置 ),然后分别对左右子表重复上述过程,直至每一个子表只有一个元素的时候,排序完成。 ↩︎