冒泡排序
基于“交换”的排序:根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置
//交换
void swap(int &a,int &b){int temp = a;a = b;b = temp;
}//冒泡排序
void BubbleSort(int A[],int n){for(int i=0;i<n-1;i++){bool flag = false; //表示本趟冒泡是否发生交换的标志for(int j = n-1;j>i;j--)if(A[j-1]>A[j]){swap(A[j-1],A[j]);flag = true;}if(flag == false) return ; //本趟遍历后没有发生交换,说明表已经有序}
}
算法性能分析
是否适用于链表?
适用,可从前往后“冒泡”,每⼀趟将更⼤的元素“冒”到链尾
快速排序
算法思想
//用第一个元素将待排序元素划分为左右两个部分
int Partition(int A[],int low,int high){int pivot = A[low];while(low<high){while(low<high&&A[high]>=pivot) --high;A[low] = A[high];while(low<high&&A[low]<=pivot) ++low;A[high] = A[low];}A[low] = pivot;return low;
}//快速排序
void QuickSort(int A[],int low,int high){if(low<high){int pivotpos = Partition(A,low,high);QuickSort(A,low,pivotpos);QuickSort(A,pivotpos,high);}
}
算法效率分析
时间复杂度=O(n*递归层数)
空间复杂度=O(递归层数)
时间复杂度 | 空间复杂度 | |
---|---|---|
最好 | O(nlog2n) | O(log2n) |
最坏 | O(n2) | O(n) |
若每⼀次选中的“枢轴”将待排序序列划分为很不均匀的两个部分,则会导致递归深度增加,算法效率变低
若初始序列有序或逆序,则快速排序的性能最差(因为每次选择的都是最靠边的元素)
若每⼀次选中的“枢轴”将待排序序列划分为均匀的两个部分,则递归深度最⼩,算法效率最⾼
快速排序算法优化思路:尽量选择可以把数据中分的枢轴元素。
eg:①选头、中、尾三个位置的元素,取中间值作为枢轴元素;②随机选⼀个元素作为枢轴元素
注:408原题中说,对所有尚未确定最终位置的所有元素进行⼀遍处理称为“⼀趟”排序,因此⼀次“划分”≠⼀趟排序。
⼀次划分可以确定⼀个元素的最终位置,而⼀趟排序也许可以确定多个元素的最终位置。