堆排序
时间复杂度
- 完全二叉树 : 除了最后一层, 所有层达到最大结点数, 最后一层结点靠左排列
- 完美二叉树 : 所有层达到最大结点数 (一种特殊的完全)
- 堆 : 一种完全二叉树, 每一个结点的值都不大于父结点(大顶堆), 都不小于父结点(小顶堆)
- 完全二叉树采用数组存储, 父结点是 (i-1)/2; 左孩子是 (i2+1); 右孩子是(i2+2)
- 堆排序分为两步 (升序)
- 构造大顶堆 (O(n))
- 将大顶堆头部元素和最后一个元素交换, 然后对剩下的元素进行大顶堆化 (O(nlogn)) (大顶堆化的时间复杂度O(logn), 需要进行n-1次) (插入的时间复杂度也是O(logn))
void swap(vector<int>& v, int i, int j)
{
int temp = v[i];
v[i] = v[j];
v[j] = temp;
}
void heapify(vector<int>& v, int index, int n)
{
int l = 2 * index + 1;
int r = 2 * index + 2;
while(l < n)
{
int largest_index;
if (v[l] < v[r] && r < n)
largest_index = r;
else
largest_index = l;
if (v[index] < v[largest_index])
swap(v, index, largest_index);
index = largest_index;
l = 2 * index + 1;
r = 2 * index + 2;
}
}
void create_heap(vector<int>& v)
{
for (int i = 1; i < v.size(); i++)
{
int cur = i;
int parent = i;
while(cur > 0)
{
parent = (cur - 1) / 2;
if (v[cur] > v[parent])
swap(v, cur, parent);
cur = parent;
}
}
}
void printV(vector<int>& v)
{
for (int i : v)
cout<<i<<" ";
cout<<endl;
}
void stackSort(vector<int>& v)
{
create_heap(v);
printV(v);
int n = v.size();
while(n > 1)
{
swap(v, 0, n-1);
n--;
heapify(v, 0, n);
}
printV(v);
}
KMP 算法
class KMP
{
public:
vector<vector<int>> dp;
string pat;
KMP(string patten)
{
this->pat = patten;
long M = pat.size();
dp.assign(M, vector<int>(256, 0));
dp[0][pat[0]] = 1;
int x = 0;
for (int j = 1; j < M; j++)
{
for (int c = 0; c < 256; c++)
dp[j][c] = dp[x][c];
dp[j][pat[j]] = j + 1;
x = dp[x][pat[j]];
}
}
int search(string txt)
{
int M = pat.size();
int N = txt.size();
int j = 0;
for (int i = 0; i < N; i++)
{
j = dp[j][txt[i]];
if (j == M) return (i - M + 1);
}
return -1;
}
};