排序算法分为交换类排序,插入类排序,选择类排序,归并类排序:
交换排序分为:1.冒泡排序。2.快速排序
基本思想:从后往前(或从前往后)两两比较相邻元素的值,若A[j-1]>A[j](或A[j-1]结果是将最小的元素交换到待排序列的第一个位置。关键字最小的元素如起泡一般逐渐往上“漂浮”直至“水面”。下一趟冒泡时,前一趟确定的最小元素不在参与比较,每一趟冒泡的结果是把序列中最小的元素放到了序列的最终位置……这样最多做n-1趟冒泡就能把所有元素排好序。

动画演示:
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
随机生成10个元素->打印生成的元素顺序->通过冒泡排序对元素进行排序->再次打印元素顺序。
#include
#include
#include typedef int ElemType;
typedef struct {ElemType *elem; // 整型指针int TableLen; // 存储动态数组里边元素的个数,相当于之前的len
}SSTable;// 初始化链表
void ST_Init(SSTable &ST,int len){ST.TableLen=len;ST.elem= (ElemType*)malloc(sizeof(ElemType)*ST.TableLen);int i;srand(time(NULL));// 生成随机数for(i=0;ii;j--){if(A[j-1]>A[j]){swap(A[j-1],A[j]);flag=true;}}if(flag==false){// 如果一趟比较没有发生任何交换,说明有序,提前结束排序return;}}
}
int main() {SSTable ST;ST_Init(ST,10);ST_print(ST);BubbleSort(ST.elem,10);ST_print(ST);return 0;
}
F:\Computer\Project\practice\16\16.4-Bubbling\cmake-build-debug\16_4_Bubbling.exe29 52 39 55 20 43 16 89 61 66 16 20 29 39 43 52 55 61 89进程已结束,退出代码为 0

冒泡排序考研中以选择题为主。
快速排序的核心是分治思想:假设我们的目的依然是从小到大的顺序排列。我们找到数组中的一个分割值,把比分割值小的数都放在数组的左边,把比分割值大的数都放在数组的右边,这样分割值的位置就被确定。数组一分为二,我们只需排前一半数组和后一半数组。复杂度直接减半。采用这种思想,不断地进行递归,最终分割得只剩下一个元素,整个序列自然就是有序的。
动画演示:
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
步骤:随机生成10个元素->打印生成的元素顺序->通过快速排序对元素进行排序->再次打印元素顺序。
#include
#include
#include typedef int ElemType;
typedef struct {ElemType *elem; // 整型指针int TableLen; // 存储动态数组里边元素的个数,相当于之前的len
}SSTable;// 初始化链表
void ST_Init(SSTable &ST,int len){ST.TableLen=len;ST.elem= (ElemType*)malloc(sizeof(ElemType)*ST.TableLen);int i;srand(time(NULL));// 生成随机数for(i=0;i=pivot ){ // 从后往前遍历,找到一个比分割值小的high--;}A[low]=A[high]; // 把比分割值小的那个元素,当道A[low]while (low
F:\Computer\Project\practice\16\16.6-quick\cmake-build-debug\16_6_quick.exe55 72 33 14 44 48 47 97 73 3914 33 39 44 47 48 55 72 73 97进程已结束,退出代码为 0
最好和平均时间复杂度为O(nlog2nnlog_2 nnlog2n),最差为O(n2n^2n2)
空间复杂度是O(log2nlog_2 nlog2n),因为递归的次数是log2nlog_2 nlog2n,而每次递归的形参都是需要占用空间的。
快速排序考研中大题概率较高。
插入排序分为:1.直接插入排序。2.折半插入排序。3.希尔排序。
考研选择题为主。
这里只讲直接插入排序的原理和实战。
如果一个序列只有一个数,那么该序列自然是有序的。插入序列首先将第一个数视为有序序列,然后把后面9个数视为依次要插入的序列。首先,我们通过外层循环控制要插入的数,用insertVal保存要插入的值87,我们比较arr[0]是否大于arr[1],即3是否大于87,由于不大于,因此不发生移动,这时有序序列是3,87。接着,将数值2插入有序序列,首先将2赋给insertVal,这时判断87是否大于2,因为87大于2,所以将87向后移动,将2覆盖,然后判断3是否大于2,因为3大于2,所以3移动到原来87的位置。内层循环结束,这时将2赋给arr[0],也就是原来3的位置。继续循环会将数依次插入有序序列,最终使整个数组有序。
动画演示:
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
#include
#include
#include typedef int ElemType;
typedef struct {ElemType *elem; // 整型指针int TableLen; // 存储动态数组里边元素的个数,相当于之前的len
}SSTable;// 初始化链表
void ST_Init(SSTable &ST,int len){ST.TableLen=len;ST.elem= (ElemType*)malloc(sizeof(ElemType)*ST.TableLen);int i;srand(time(NULL));// 生成随机数for(i=0;i=0&&arr[j]>insertVal;j--){ // 内层控制比较j要大于等于0,同时arr[j]大于insertval,arr[j]位置元素往后覆盖arr[j+1]=arr[j];}arr[j+1]=insertVal;}
}
int main() {SSTable ST;ST_Init(ST,10);ST_print(ST);InsertSort(ST.elem,10);ST_print(ST);return 0;
}
F:\Computer\Project\practice\16\16.7-insert\cmake-build-debug\16_7_insert.exe19 41 89 67 1 57 57 15 53 661 15 19 41 53 57 57 66 67 89进程已结束,退出代码为 0
随着有序序列不断增加,插入排序比较的次数也会增加,插入排序的执行次数也是从1加到n-1,总运行次数为n(n-1)/2,所以时间复杂度为O(n2n^2n2)。因为未使用额外的空间,所以空间复杂度为O(1)。
如果数组本身有序,那么最好的时间复杂度是O(n)。