本章没有仔细看的部分:二分查找P127-P130
排序
1.选择排序
枚举n次,每次选择最小的放大第一个里
#include <cstdio>
void swap(int* p,int* q)
{
int temp = *p;
*p = *q;
*q = temp;
}
void selectSort(int array[])
{
int i,j,min,index;
for (i = 0;i < sizeof(array);i++)
{
min = array[i];
index = i;
for (j = i+1; j < sizeof(array); j++)
index = array[j]<array[index]?j:index;
swap(&array[index],&array[i]);
printf("%d ",array[i]);
}
}
2.插入排序
将后边的一个数插入到前边有序部分的适当位置
#include <cstdio>
void insertSort(int array[])
{
int i,j;
for (i = 0;i < sizeof(array);i++)
{
for (j = i-1; j >= 0 ; j--) {
if (array[j+1] < array[j]) {
swap(&array[j+1],&array[j]);
}
}
}
for (i = 0; i < sizeof(array); i++) {
printf("%d ",array[i]);
}
}
这个代码是错的,因为sizeof使用错误
正确的如下
void insertSort(int *array,int len) {
int i, j, temp;
for (i = 1; i < len; i++) //进行 n-1趟排序
{
temp = array[i];
for (j = i - 1; j >= 0; j--) {
if (temp < array[j]) {
array[j + 1] = array[j];
} else {
break;
}
}
array[j + 1] = temp;
}
int k;
for (k = 0; k < sizeof(array); k++) {
printf("%d ", array[k]);
}
}
错误的原因:在函数外部,sizeof(array)表示数组的元素所占的字节数,在insertSort内部,sizeof(array)与元素长度无关,永远都是8。
3.排序与sort
sort(首元素地址,尾元素下一个地址,比较函数(非必填))
比较函数为cmp
PAT A1025
散列
1.散列的定义与整数散列
key ->H(key) ->value
直接定址法、除留余数法、平方取中法、
直接定址法: 恒等变换 H(key)=key 线性变换:H(key) = a*key +b
除留余数法:H(key) = key%mod
方便起见:mod = Tsize (素数)
1 2 重新计算值,所以又叫开放定址法
1.线性探查法 H(key) = H(key) + 1 容易导致扎堆,降低效率
2.平方探查法 H(key) = H(key)+1^2 H(key)-1^2 H(key)+2^2 H(key)-2^2 ...... H(key) +k^2 %Tsize H(key)-k^2<0?((H(key)+-k^2) % TSize +TSize)%TSize 即不断加TSize直到出现第一个非负数为止
3.链接地址法 Link[0] ~Link[mod-1] 单链表数组,冲突的就加到相应的链表后边
字符串hash初步:可以将字符串看作16进制数,进而可以转成唯一的十进制数
递归
分治 :分解 解决 合并
递归 :
n! Fibonacci数列 全排列 n皇后问题 回溯剪枝
贪心
1 简单贪心 PAT B1020 月饼 PAT B1023组个最小数
2 区间贪心 不相交区间 区间选点问题
二分
1 二分查找 分区间 [left,mid-1] [mid] [mid + 1,right]
二分查找可以归结为查找有序序列中第一个满足某条件的元素
应该特别注意while循环结束的条件和条件判断>、>=、<、<=
书里给了固定模板P129
2 二分拓展
给定一个区间 [ L,R] 上的单调函数,求方程f(x)的根
比较f(mid)与0的大小,根据left,right区间的关系选择合适的区间
装水问题 木棒问题(二分答案,一个一个找)
3 二分幂
two pointers
1 two pointers最原始是为了解决有序序列两数之和的问题
2 归并排序
3 快速排序
其它
1 打表 例:斐波那契数列
2 递推 找规律
3 随机选择算法 快排的拓展思路