这里写目录标题
- 1.查找
- 1.1顺序查找
- 1.2折半查找
- 1.3哈希表
- 2.顶堆
- 3.排序
- 3.1直接插入排序
- 3.2希尔排序
- 3.3计数排序
- 3.4简单选择排序
- 3.5堆排序
- 3.6冒泡排序
- 3.7快速排序(分治,归位)
- 3.8归并排序
1.查找
查找表:同一类型的数据元素构成的集合
静态查找表:数据元素是否存在及其属性
有顺序查找,折半(二分)查找,分块查找
动态查找表:插入和删除数据元素
有二叉排序树,平衡二叉树,B_树,哈希表
关键字:数据元素的某个数据项的值
主关键字(唯一),次关键字(多个)
1.1顺序查找
适用于顺序查找和链式查找,不需要有序
平均查找长度:ASL = (n + 1) / 2
1.2折半查找
适用于顺序存储,递增排序
n < mid,右边
n > mid,左边
n = mid,return 下标
最多比较⌊log₂n」+ 1
1.3哈希表
哈希表H,两个关键字K₁,K₂
K₁ ≠ K₂但H(K₁) = H(K₂)称为冲突
同义词:H(6) = 1,H(8) = 1
哈希函数构造:
出留取余法:H(key) = key % m = 地址
一共有n个元素,m一般取接近n但≯n的质数
解决冲突:
1.开放地址法
线性探测法:(结果+i)%m,i表示冲突的次数
二次探测法:(结果+i)%m,
i是1²,-(1)²,2²,-(2)²,3²,-(3)²…
2.链地址法:
哈希表查找
与哈希函数,处理冲突的方法,哈希表的装填因子有关
装填因子=表中装填的记录数/哈希表的长度
装填因子越小,发生冲突的可能性越小,反之越大
2.顶堆
3.排序
排序算法 | 平均 | 最坏 | 最好 | 空间 | 稳定性 |
---|---|---|---|---|---|
直接插入排序 | O(n²) | O(n²) | O(n) | O(1) | 稳定 |
冒泡排序 | O(n²) | O(n²) | O(n) | O(1) | 稳定 |
希尔排序 | O(n^1.3) | O(n²) | O(n) | O(1) | 不稳定 |
简单选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 |
堆排序 | O(nlog₂n) | O(nlog₂n) | O(nlog₂n) | O(1) | 不稳定 |
快速排序 | O(nlog₂n) | O(n²) | O(nlog₂n) | O(log₂n) | 不稳定 |
归并排序 | O(nlog₂n) | O(nlog₂n) | O(nlog₂n) | O(n) | 稳定 |
3.1直接插入排序
基本有序适用于直接插入排序
从第二个元素开始与前比较
插入的数>=放后面
插入的数<放前面
局部有序,每次不能确定最终位置
3.2希尔排序
将整个序列分成若干子序列,分别进行直接插入排序
最后一趟,整个为一组进行直接插入排序
3.3计数排序
只有1-9
先记下每个数字有几次,在从小到大排序
3.4简单选择排序
可以归位(却定元素的最终位置)
int selection(int[] a,int n){
for(int i = 0;i < n - 1;i++){
//遍历数组
int min = i;//假设第一个数是最小的
for(int j = i + 1;j < n;j++){
//从第二个数开始,与第一个数比较
if(a[j] < a[min]){
min = j;
}
}
if(min != i){
int temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
}
进行n-1 趟排序
3.5堆排序
将元素化成大顶堆,交换第一个和最后一个数,可以确定最大的数的位置,再构成大顶堆再交换,直到完成排序
大顶堆排完后是递增序列
小顶堆排完后是递减序列
3.6冒泡排序
/*
1.一共有n个数
2.进行了n-1轮排序,可以看成外层循环
3.每一轮可以确定一个数的位置
4.如果前>后就交换位置(从小到大)
5.每轮比较n-i-1次*/
public class 冒泡排序 {
public static void main(String[] args) {
int[] arr = {23,25,15,8,96,108};
int temp = 0;
for(int i = 0;i < arr.length-1;i++){
for(int j = 0;j < arr.length - i - 1;j++){
if(arr[j] > arr[j + 1]){
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
for(int i = 0;i < arr.length;i++) {
System.out.println(arr[i]);
}
}
}
3.7快速排序(分治,归位)
/*
设置两个变量i,j
它们的初值分别指向第一个记录和最后一个记录
设置一个pivot,通常是第一个记录
先从后往前找第一个 < pivot的记录
a[i] = a[j]
从前往后找第一个 > pivot的记录
a[j] = a[i]
重复,直至i = j
*/
void quick_sort(int[] a,int l,int r){
if(l >= r) return;
int i = l,j = r,pivot = a[l];
while(i < j){
while(i < j && j >= pivot)j--;
a[i] = a[j];
while(i < j && i <= pivot)i++;
a[j] = a[i];
}
a[i] = pivot;//重新开始
quick_sort(a,l,i - 1);
quick_sort(a,i + 1,r)
}
3.8归并排序
将一组数据/2ˣ,直到结果为1,然后进行合并
void merge_sort(int[] a,int l,int r){
if(r >= l) return;
int mid = (l + r) / 2;
merge_sore(a,l,mid);
merge_sore(a,mid + 1,r);
//将一组数据/2ˣ,直到结果为1
int i = l,j = mid + 1,k = 0;
//k是辅助数组t[]的下标
while(i <= mid && j <= r){
if(a[i] <= a[j]){
t[k++] = a[i++];
}else{
t[k++] = a[j++];
}
}
while(i <= mid)t[k++] = a[i++];
while(j <= r)t[k++] = a[j++];
for(i = l,j = 0;i <= r;i++,j++)a[i] = t[j];
}