数据结构交换排序的实现
交换排序分为冒泡排序和快速排序
1. 冒泡排序
冒泡排序是一种稳定的排序算法,基本思想:从后往前或从前往后两两比较相邻的关键字,若顺序错误,则交换他们的位置,并不断向前进行比较大小,直到最小或最大的关键字在待排序列的第一个位置,这样一趟排序就完成了,然后开始下一个关键字的排序,整体的过程就像气泡浮出水面一般。注意:每趟排序都会将一个元素放到其最终位置,最坏和平均时间复杂度均为:O(n²),空间复杂度:O(1)。
![](https://images2017.cnblogs.com/blog/849589/201710/849589-20171015223238449-2146169197.gif)
void BubbleSort(ElemType A[], int n) {
int i, j, temp;
for (i = 0; i < n - 1; i++) {
for (j = n - 1; j > i; j--) { //从后往前开始进行比较
if (A[j - 1] > A[j]) {
temp = A[j - 1];
A[j - 1] = A[j];
A[j] = temp;
}
}
}
}
2. 双向冒泡排序算法
基本思想:在正反两个方向交替进行扫描,第一趟把最大关键字放在后面;第二趟把最小关键字放在前面,如此反复。
void TwoBubbleSort(ElemType A[], int n) {
int low = 0, high = n - 1, i, temp;
bool flag = true; //判断一趟冒泡排序后是否交换
while (low < high && flag) { //当flag为false说明排序完成
flag = false;
for (i = low; i < high; i++) { //从前向后冒泡
if (A[i] > A[i + 1]) { //把更大的关键字放在后面
temp = A[i];
A[i] = A[i + 1];
A[i + 1] = temp;
flag = true; //交换完成
}
}
high--; //因为更大的关键字占了一个位置,因此high往左边后退一格
for (i = high; i > low; i--) { //从后往前冒泡
if (A[i] < A[i - 1]) { //把更小的关键字放在前面
temp = A[i];
A[i] = A[i - 1];
A[i - 1] = temp;
flag = true; //交换完成
}
}
low++; //因为更小的关键字占了一个位置,因此low往后边前进一格
}
}
3. 快速排序
快速排序,是一种不稳定算法,基本思想:快速排序基于分治法的思想,即以pivot作为枢轴,把比他小的放在左边,比他大的放在右边,一趟排序后pivot放在了其最终的位置,因此每趟排序都会将一个元素放到其最终位置,完成一趟排序之后,则对其左右两边的子序列重复进行快速排序,直到所有序列有序。最坏时间复杂度:O(n²),最好及平均复杂度:O(n㏒₂n),最坏空间复杂度:O(n),最好及平均空间复杂度:O(㏒₂n),注意:快速排序是所有内部排序算法中平均性能最优的排序算法。
![](https://images2017.cnblogs.com/blog/849589/201710/849589-20171015230936371-1413523412.gif)
int Partition(ElemType A[], int low, int high) {
ElemType pivot = A[low];
while (low < high) { //跳出递归的条件
while (low < high && A[high] >= pivot)
high--;
A[low] = A[high]; //将比pivot小的元素移动到左边
while (low < high && A[low] <= pivot)
low++;
A[high] = A[low]; //将比pivot大的元素移动到右边
}
A[low] = pivot; //枢纽元素放到最终位置
return low; //返回存放枢纽元素的最终位置
}
void QuickSort(ElemType A[], int low, int high) {
if (low < high) { //跳出递归的条件
int pivotpos = Partition(A, low, high); //划分
QuickSort(A, low, pivotpos - 1); //依次对两个子表进行递归排序
QuickSort(A, pivotpos + 1, high);
}
}