2024.1.16
目录
1、 算法有很多种(后面会完成相关笔记),其中排序和查找两种算法是研究得比较成熟的;
4、 在C++的 STL (Standard Template Libary)中
1、 qsort在头文件 stdlib 中;下面分析这个函数的原型;
2. 注意:只有整型类数组的排序可以这样用;别的类型基本上不可以!
上午:
一、排序
排序(具体可参考数据结构倒数第二章)是一种算法(解决某个特定问题的步骤),分析算法时,从时间复杂度和空间复杂度两个方面进行考虑和平衡;物美价廉是偶尔,一分钱一分货是常态;
-
时间复杂度
时间:同一台电脑运行不同的算法程序,进行时间的比较;时间越短,算法越优秀;快排远好于冒泡;
2. 空间复杂度;
内存:解决了同样的问题,使用内存越少,算法越优秀;
二、 从时间复杂度对排序算法进行分类
1、 算法有很多种(后面会完成相关笔记),其中排序和查找两种算法是研究得比较成熟的;
2、 三类排序算法;
前两个比较掌握,需要会手写,解释;对第三个,不需要会写(当然会写最好),会用;
i. 慢;冒泡;
冒泡排序:比较相邻的两个元素,如果顺序不对则交换它们的位置。从左到右(或者从上到下)重复这个过程,直到整个 序列都被排序。时间复杂度为O(n^2)。
ii. 中;选择;
直接插入排序:将未排序的元素逐个插入到已排序部分的合适位置,使得已排序部分始终保持有序。时间复杂度为O(n^2)。
iii. 快;快速;
简单选择排序:每次从未排序的部分中选择最小(或最大)的元素,然后将其放到已排序部分的末尾。重复这个过程,直到所有元素都被排序。时间复杂度为O(n^2)。
简称快排,现今最快的排序算法;几乎所有的编程语言实现,都采用这种算法。
3、 对于快排,早在学习C语言时
包含进来的头文件stdlib中,就提供了快速排序算法,我们将这个头文件包含进来,使用其中的 qsort 函数即可实现针对 任何 类型 数组 的快速排序;
4、 在C++的 STL (Standard Template Libary)中
在各种实现的具体数据结构中,比如list,set,vector等,都提供了快速排序算法;
三、 qsort算法;
1、 qsort在头文件 stdlib 中;下面分析这个函数的原型;
i. 此函数没有返回值;void
ii. 函数名:qsort
iii. 四个参数;
1. 参数1;数组名;array
2. 参数2;数组长度;10
3. 参数3;每个元素长度; sizeof(int)
4. 参数4;函数指针;
2、 一维整数数组的排序示例;
#include "gaoming.hpp"
void test();
int main() {
printf("\n");
test();
printf("\n");
return 0;
}
int asc(const void *, const void *);
void test() {
/*
int add (int a, int b )
void qsort(void *array,int nn,int size,int (*PtFunc)(const void*,const void *));
*/
int array[]{11, 78, 85, 100, -89, 41,};
int nn = sizeof array / sizeof *array;
cout << "*** 源数组 ***" << endl;
cout << array << endl;
printf("\n");
qsort(array, nn, sizeof(*array), asc);
cout << "*** 升序之后 ***" << endl;
cout << array << endl;
}
int asc(const void *a, const void *b) {
int *p1 = (int *) a;
int *p2 = (int *) b;
int e1 = *p1;
int e2 = *p2;
if (e1 < e2) {
return -1;
} else if (e1 > e2) {
return 1;
} else {
return 0;
}
}
四、 课堂练习一
利用上面讲述的 qsort 对一维整型数组的排序,自行设计一个实型数组,对其分别进行 升序 和 降序 排序,并分配用重载的 << 进行输出;
参考代码:
int descByDoubleArray(const void *a, const void *b) {
double *p1 = (double *) a;
double *p2 = (double *) b;
double e1 = *p1;
double e2 = *p2;
if (e1 < e2) {
return 1;
} else if (e1 > e2) {
return -1;
} else {
return 0;
}
}
void test() {
double dd[]{1.25, -3.1415, 2.71828, 5.5124, 123.54, -78.6542,};
cout << "*** 源数组 ***" << endl;
cout << dd << endl;
printf("\n");
cout << "*** 降序 ***" << endl;
qsort(dd, sizeof dd / sizeof *dd, sizeof(*dd), descByDoubleArray);
cout << dd << endl;
}
错误原因:
原来的程序运行不对,可能是因为Xcode和DVEC++的编译器有一些差异,导致对数组的打印方式不同。Xcode使用的是Clang编译器,而DVEC++使用的是GCC编译器。这两种编译器在处理C++标准库的一些细节上可能有不同的实现,比如对于cout << dd这样的语句,Clang会打印出数组的地址,而GCC可能会打印出数组的元素。这也是为什么老师的代码在DVEC++上可以正常运行,而在Xcode上却出现了问题。
Xcode能运行的代码:(其余未变)
void test() {
double dd[]{1.25, -3.1415, 2.71828, 5.5124, 123.54, -78.6542};
int n = sizeof dd / sizeof *dd; // get the size of the array
cout << "*** 源数组 ***" << endl;
// use a for loop to print the original array
for (int i = 0; i < n; i++) {
cout << dd[i] << " ";
}
cout << endl;
printf("\n");
cout << "*** 降序 ***" << endl;
qsort(dd, n, sizeof(*dd), descByDoubleArray);
// use another for loop to print the sorted array
for (int i = 0; i < n; i++) {
cout << dd[i] << " ";
}
cout << endl;
}
-
整数数组的升序规则函数的优化;
int ascByIntArray(const void *a, const void *b) {
return *((int *) a) -*((int * b);
}
2. 注意:只有整型类数组的排序可以这样用;别的类型基本上不可以!
int ascByIntArray(const void *, const void *);
int descByDoubleArray(const void *, const void *);
void test() {
int array[]{11, 78, 85, 100, -89, 41,};
int nn = sizeof array / sizeof *array;
cout << "*** 源数组 ***" << endl;
cout << array << endl;
printf("\n");
qsort(array, nn, sizeof(*array), ascByIntArray);
cout << "*** 升序之后 ***" << endl;
cout << array << endl;
printf("\n");
double dd[]{1.251, 3.1415, 1.252828, 1.25124, 123.54, 3.14159,};
cout << "*** 源数组 ***" << endl;
cout << dd << endl;
printf("\n");
cout << "*** 降序 ***" << endl;
qsort(dd, sizeof dd / sizeof *dd, sizeof(*dd), descByDoubleArray);
cout << dd << endl;
}
int ascByIntArray(const void *a, const void *b) {
return *((int *) a) - *((int *) b);
}
int descByDoubleArray(const void *a, const void *b) {
double e1 = *((double *) a);
double e2 = *((double *) b);
if (e1 < e2) {
return 1;
} else if (e1 > e2) {
return -1;
} else {
return 0;
}
}