数据结构-08交换排序
冒泡排序
算法思想: 将从后往前依次比较两个元素的大小,让小的元素一步一步移动到表的最前面,每一趟冒泡会确定一个元素,最多n-1次,完成所有元素的排序
void BubbleSort(int arr[], int len){
for(int i=0;i<len-1;i++){
bool flag = false; // 表示本趟冒泡是否发生交换的标志
for(int j=len-1;j>i;j--){ // j每次从表尾开始,向前遍历
if(arr[j]<arr[j-1]){ // 若前驱大于j指向的元素,交换元素位置
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
flag = true; // 若发生元素交换,修改信号变量
}
if(!flag) return; // 本次遍历中没有发生交换,说明表已经有序
}
}
算法分析
空间复杂度:O(1)
时间复杂度:
🐉最好:O(n) 所有元素都已经排好序
🐉最坏:O(n2)
🐉平均:O(n2))
稳定性:稳定
适用性: 顺序存储和链式存储的线性表
ps:若最初表为逆序,则每次比较都需要移动元素,此时元素比较次数为n(n-1)/2,元素的移动次数是3*n(n-1)/2。 因为元素交换的步骤为:
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
02 快速排序
算法思想: 每次确定一个枢纽元素pivot的位置,首先确定该枢纽元素的位置,设置两个指针指向表的两端,每次移动一个元素。将右侧小于pivot的元素,移动到左端,然后将左侧中大于pivot的元素移动至右端,循环,直到low与high指针指向同一下标。
int Partition(int arr[], int low, int high){
int pivot = arr[low]; // 使用pivot保存枢纽元素,这里选定的是表中第一个元素
while(low<high){ //
while(low<high && arr[high]>=pivot) // 从右侧开始查找,找到第一个小于枢纽的元素
high--;
arr[low] = arr[high]; // 将小于枢纽的元素移动至左端
while(low<high && arr[low]<=pivot) // 从左侧开始查找,找到第一个大于枢纽的元素
low++;
arr[high] = arr[low]; // 将大于枢纽的元素移动至右端
}
arr[low] = pivot; // 此时,low==high, 也就是指向了枢纽元素在最终数组中的位置
return low; // 将本轮的枢纽元素下标返回
}
void QuickSort(int arr[], int low, int high){
if(low<high){ // 递归跳出条件
int pivot_pos = Partition(arr, low, high); // 确定一个元素的位置,根据该下标划分左右子表
QuickSort(arr, low, pivot_pos-1); // 处理左子表
QuickSort(arr, pivot_pos+1, high); // 处理右子表
}
}
算法分析:
空间复杂度
🐉 最好:O(log2n)
🐉 最坏:O(n)
🐉 平均:O(log2n)
时间复杂度
🐉 最好:O(nlog2n)
🐉 最坏:O(n2)
🐉 平均:O(nlog2n)
稳定性: 不稳定
适用性: 顺序存储的线性表