赞
踩
目录
基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。
首先我们先介绍并创建两个函数,后面要用
Swap
的函数实现了交换两个整数指针所指向的值
- void Swap(int* p1, int* p2)
- {
- int tmp = *p1;
- *p1 = *p2;
- *p2 = tmp;
- }
定义了一个名为GetMidi
的函数用于确定三个位置begin
、midi
和end
在数组a
中的中间值索引,确定并返回中间值的索引
- int GetMidi(int* a, int begin, int end)
- {
- int midi = (begin + end) / 2;
- // begin midi end 三个数选中位数
- if (a[begin] < a[midi])
- {
- if (a[midi] < a[end])
- return midi;
- else if (a[begin] > a[end])
- return begin;
- else
- return end;
- }
- else // a[begin] > a[midi]
- {
- if (a[midi] > a[end])
- return midi;
- else if (a[begin] < a[end])
- return begin;
- else
- return end;
- }
- }
- void BubbleSort(int* a, int n)//冒泡排序
- {
- for (int j = 0; j < n; j++)
- {
- bool exchange = false;
- for (int i = 1; i < n - j; i++)
- {
- if (a[i - 1] > a[i])
- {
- Swap(&a[i - 1], &a[i]);
- exchange = true;
- }
- }
-
- if (exchange == false)
- break;
- }
- }
冒泡排序的特性总结:
1. 冒泡排序是一种非常容易理解的排序
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1)
4. 稳定性:稳定
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,
其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
- // 假设按照升序对array数组中[left, right)区间中的元素进行排序
- void QuickSort(int array[], int left, int right)
- {
- if(right - left <= 1)
- return;
- // 按照基准值对array数组的 [left, right)区间中的元素进行划分
- int div = partion(array, left, right);
- // 划分成功后以div为边界形成了左右两部分 [left, div) 和 [div+1, right)
- // 递归排[left, div)
- QuickSort(array, left, div);
- // 递归排[div+1, right)
- QuickSort(array, div+1, right);
- }
上述为快速排序递归实现的主框架,发现与二叉树前序遍历规则非常像,同学们在写递归框架时可想想二叉树前序遍历规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可。
将区间按照基准值划分为左右两半部分的常见方式有:
在快速排序算法中,需要在找到左边比关键值大的元素和右边比关键值小的元素之后才进行元素交换,以确保左边的元素都比关键值小,右边的元素都比关键值大。但是在代码中目前的交换步骤存在问题,因为在while
循环结束之后直接进行了一次元素交换,而应该是在找到左右指针位置后再进行交换。
- int QuickSort1(int* a, int begin, int end)
- {
- int midi = GetMidi(a, begin, end);
- Swap(&a[midi], &a[begin]);
-
- int left = begin, right = end;
- int keyi = begin;
-
- while (left < right)
- {
- // 右边找小
- while (left < right && a[right] >= a[keyi])
- {
- --right;
- }
-
- // 左边找大
- while (left < right && a[left] <= a[keyi])
- {
- ++left;
- }
-
- Swap(&a[left], &a[right]);
- }
-
- Swap(&a[left], &a[keyi]);
-
- return left;
- }
a[begin]
。begin
和end
分别指向数组的起始和末尾,开始移动指针以找到需要交换的元素。begin
小于end
时,进行以下操作:
end
指针的位置。begin
指针的位置。- //2.挖坑法
- int QuickSort2(int* a, int begin, int end)
- {
- int midi = GetMidi(a, begin, end);
- Swap(&a[midi], &a[begin]);
-
- int key = a[begin];
- int hole = begin;
- while (begin < end)
- {
- // 右边找小,填到左边的坑
- while (begin < end && a[end] >= key)
- {
- --end;
- }
-
- a[hole] = a[end];
- hole = end;
-
- // 左边找大,填到右边的坑
- while (begin < end && a[begin] <= key)
- {
- ++begin;
- }
-
- a[hole] = a[begin];
- hole = begin;
- }
-
- a[hole] = key;
- return hole;
- }
将数组分成两个子数组,左边的子数组中的元素都小于等于中间元素,右边的子数组中的元素都大于等于中间元素,并返回中间元素的索引
- int QuickSort3(int* a, int begin, int end)
- {
- int midi = GetMidi(a, begin, end);
- Swap(&a[midi], &a[begin]);
- int keyi = begin;
-
- int prev = begin;
- int cur = prev + 1;
- while (cur <= end)
- {
- if (a[cur] < a[keyi] && ++prev != cur)
- Swap(&a[prev], &a[cur]);
-
- ++cur;
- }
-
- Swap(&a[prev], &a[keyi]);
- keyi = prev;
- return keyi;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。