交换排序——冒泡排序和快速排序

希尔排序是直接插入排序的升级;堆排序是简单选择排序的升级;

快速排序是冒泡排序的升级,它们都属于交换排序;

冒泡排序(Bubble Sort)的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序为止。

流程:

第1趟冒泡:将第1个元素和第2个元素进行比较,若为反序,则将两个元素交换,然后比较第2个元素和第3个元素。依次类推,直到第 n-1个元素和第 n个元素进行比较为止。其结果使最大值元素被放置在最后一个位置(第 n个位置)。

第2趟冒泡:对前 n-1个元素进行同样操作,其结果是使第二大元素被放置在倒数第二个位置上(第 n-1个位置)。

……

第n-1趟冒泡:将第1个元素和第2个元素进行比较,若为反序,则将两个元素交换。

完成全部记录的排序。

vector<int> bubbleSort(vector<int> list) {//冒泡排序
	vector<int> result;
	if (list.empty()) {
		return result;
	}
	result = list;
	int temp;
	for (int i = 0; i < result.size() - 1;++i) {// 要遍历的次数
		bool bChanged = false;//交换标志位
		for (int j = 0; j < result.size() - 1 - i;j++) {//从后向前依次的比较相邻两个数的大小
			if (result[j+1]<result[j]) {//如果后面的元素小,则交换它们的位置
				temp = result[j + 1];
				result[j + 1] = result[j];
				result[j] = temp;
				bChanged = true;
			}
		}
		if (false == bChanged) {//如果标志为false,说明本轮遍历没有交换,已经是有序数列,可以结束排序
			break;
		}
	}
	return result;
}

快速排序(Quick Sort)的基本思想是:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字都比另一部分记录的关键字小,然后继续按此方法分别对这两部分记录进行排序,持续递归,直到整体有序。

流程:

第1步:设定一个分界值,通过该分界值将数组分成左右两部分。(通常选取待排序第一个记录的关键字,也可以取左后一个,或者中间位置等等)

第2步:将大于等于分界值的记录放到序列右边;将小于等于分界值的记录放到序列左边;

第3步:对左边的子序列递归进行第1、2步的操作;对右边的子序列也递归进行第1、2步的操作。

……

直到完成所有子序列的递归就完成了全部记录的排序。

int division(vector<int> &list, int left, int right) {//快速排序的division函数  
    int base = list[left];// 以最左边的数(left)为基准(通常就是选取第一个元素)  
    while (left < right) {  
        while (left < right && list[right] >= base)//从序列右端开始,向左遍历,直到找到小于base的数  
            right--;  
        list[left] = list[right];// 找到了比base小的元素,将这个元素放到左边的位置  
        while (left < right && list[left] <= base)// 从序列左端开始,向右遍历,直到找到大于base的数  
            left++;  
        list[right] = list[left];//找到了比base大的元素,将这个元素放到右边的位置  
    }  
    list[left] = base;// 最后将base放到left位置。此时,left位置的左侧数值应该都比left小,而left位置的右侧数值应该都比left大  
    return left;  
}  
  
  
void quickSort(vector<int> &list, int left, int right) {// 快速排序  
    if (left < right) {// 左下标一定小于右下标,否则就越界了  
        int base = division(list, left, right);// 对数组进行分割,取出下次分割的基准标号  
        quickSort(list, left, base - 1);// 对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序  
        quickSort(list, base + 1, right);// 对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序  
    }  
}

猜你喜欢

转载自blog.csdn.net/m0_74178120/article/details/129008999