-Introduction: 最好的操作与最坏的操作,期望的操作数量
- 最好的操作计数,当然就是min(operation-p(I)) 所有操作计数里面计数次数最少的那一次
- 最差的操作计数就是max(operation-p(I)) 所有操作计数里面计数次数最多的那一次
-平均操作计数:
解释:
这里面的p(I)代表这一次操作出现的概率 * 这一次操作计数
- 假如所有的操作是等可能的出现的: 那就将p(I)替换成 1/n 其中n代表所有可能时间的总数量,每一个发生概率都是1/n
例题:
template<class T>
int SequentialSearch(T a[], const T& x, int n){
int i;
for (i = 0; i < n && a[i] != x; i++);
if (i == n) return -1 ;
return i;
}
Summary -
(1). 求期望的方法:无非也就是发生的概率乘上 每次所用掉的计数
(2). 如果是等概率的: 无非也就是每次发生的概率 = 1/(所有可能的事件数量)
1/n * (1+2+3.....)
//解释为:只用了一次操作计数就找到了,概率1/n
// 同样只用两次操作就找到了1/n.....
// 相加得到了总的概率
例题二
template<class T>
void Insert(T a[], int& n, const T& x){// 向有序数组 a [ 0 : n-1 ]中插入元素x
int i;
for (i = n-1; i >= 0 && x < a[i]; i- -)
a[i+1] = a[i];
a[i+1] = x;
n++; // 添加了一个元素
}
- 假设X被插到数组的任何位置,都是等概率发生的
- 一共有n+1个可插入位置
- 分别是比较1次(头),2次……n次(尾部前一个),n次(尾部最后)
- 1/(n+1) * (1+2+3……+n+n)
及时终止的排序过程:之前的排序有一点不好:就算后面的内容是已经排好序的,程序依旧会一直执行下去
现在设计一种能自动判断后面要不要继续执行的排序
template<class T>
void SelectionSort(T a[], int n){
bool sorted = false;
for (int size = n; !sorted && (size > 1); size--) {
int pos = 0;
sorted = true;
for (int i = 1; i < size; i++){
if (a[pos] <= a[i]) pos = i;
else sorted = false;
}
Swap(a[pos], a[size - 1 ] ) ;
}
}
- 整体思路首先是一个长度为n的数组,第一回合是着手于整个长度为n的整体数组
- 默认这个数组是一个排过序的数组
第二个for循环:确认这个数组的确是一个排过序的数组
- 并且将pos设置成这个数组里面最大的的元素
- 如果这个数组的确是排过序的,那么sorted标志是true,第一个for循环就此终止
- 如果这个数组没排过序,那么pos不仅是最大的元素,同时sorted标志是false,第一个for循环继续执行
pos由于是最大的元素,被放在数组最后一位,然后从第0到第n-2个元素
- 再执行一次->检查是否排序 -> pos是削减后数组的最大的元素 -> pos放在最后一位 -> 检查是否再来一轮
冒泡排序的及时终止优化
template<class T>
bool Bubble(T a[], int n){
bool swapped = false;
for (int i = 0; i < n - 1; i++)
if (a[i] > a[i+1]) {
Swap(a[i], a[i + 1]);
swapped = true;
}
return swapped;
}
template<class T>
void BubbleSort(T a[], int n){
for (int i = n; i > 1 && Bubble(a, i); i- -) ;
}
- 同刚刚一样,首先默认是已经排过序了
- 然后针对整个数组,检阅是否a[i+1]都大于a[i] 如果是满足的,就不进行下一轮了
- 如果不满足那就交换一次,将较大的数放在数组的最右边
- 而后将数组长度减一,对剩下来的数组再次执行检阅,调换,再次判断是否需要继续执行…..