#include<iostream>
#include<cstring>
using namespace std;
const int max_size = 100010;
// 栈
class stack {
public:
int top;
int* data;
int max_size;
stack()
{
top = 0;
data = new int[max_size];
}
~stack()
{
delete[] data;
}
bool isempty()
{
return top == 0 ? true : false;
}
bool isfull()
{
return top == (max_size - 1) ? true : false;
}
void push(int x)
{
if (!isfull())
data[++top] = x;
else
cout << "the stack is full" << endl;
}
void pop()
{
if (!isempty())
top--;
else cout << "the stack is empty" << endl;
}
void clean()
{
top = 0;
}
void printstack()
{
for (int i = top; i >= 0; i--)
cout << data[i] << " ";
}
void gettop()
{
cout << data[top] << endl;
}
};
//队列
class queue {
public:
int front;
int back;
int size; //用于记录队列中元素的个数,便于队列的判空与判满
int* data;
queue()
{
front = back = size = 0;
data = new int[max_size];
}
~queue()
{
front = back = -1;
delete[]data;
}
bool isfull()
{
return size == max_size ? true : false;
}
bool isempty()
{
return size == 0 ? true : false;
}
void push(int x)
{
if (!isfull())
data[++back] = x;
else cout << "the queue is full" << endl;
}
void pop()
{
if (!isempty())
front++;
else cout << "the queue is empty" << endl;
}
void printqueue()
{
if (!isempty())
for (int i = front; i <= back; i++)
cout << data[i];
}
};
//二叉树链表实现
class tree {
public:
int value;
tree* left;
tree* right;
tree() {};
tree(int x) : value(x), left(NULL), right(NULL){}
tree* build()
{
int x;
cin >> x;
if (x == -1)return NULL;
return new tree(x);
}
tree* find(int x, tree* root)
{
tree* tem = NULL;
if (root->value == x)return root;
if (root->left)tem = find(x, root->left);
if (tem) return tem;
if (root->right) tem = find(x, root->right);
return tem;
}
void front_search(tree* root)
{
cout << root->value << " ";
front_search(root->left);
front_search(root->right);
}
void back_search(tree* root)
{
back_search(root->left);
back_search(root->right);
cout << root->value << " ";
}
void mid_search(tree* root)
{
mid_search(root->left);
cout << root->value << " ";
mid_search(root->right);
}
int depth(tree* root)
{
if (!root) return NULL;
return max(depth(root->left), depth(root->right)) + 1;
}
};
//二叉树数组实现
/*
int tree[max_size]; 以i为目前所在节点,左子节点为2*i,右子节点为2*i+1,父节点为i/2,左右兄弟节点为i-1或i+1
void front_search(int i)
{
if(tree[i] == -1) return; 以树中value为-1作为边界
cout << tree[i] << " ";
front_search(2 * i);
front_search(2 * i + 1);
}
void back_search(int i)
{
if(tree[i] == -1) return;
back_search(2 * i);
back_search(2 * i + 1);
cout << tree[i] << " ";
}
void in_search(int i)
{
if(tree[i] == -1) return;
in_search(i * 2);
cout << tree[i] << " ";
in_search(2 * i + 1);
}
*/
// hash!hash!hash!hash!hash!hash!hash!hash can you imagine how bored i am?
typedef unsigned long long ull;
const int base = 131;
ull h[max_size], p[max_size];
char dest[max_size]; //目标字符串,最好数组下标从一开始,这样就可以不用考虑边界问题, 用scanf("%s",dest + 1);
void hash_change() //hash函数转化
{
int n = strlen(dest + 1);
p[0] = 1; //base的指数级
for (int i = 0; i < n; i++)
{
h[i] = h[i - 1] * base + dest[i] - 'a' + 1;
p[i] = p[i - 1] * base;
}
}
ull son_str(int l, int r) //字符串字串数字
{
return h[r] - h[l - 1] * p[r - l - 1];
}
// 堆
class heapstruct
{
public:
int* value;
int size; //所含元素个数
int capacity; //容量
heapstruct()
{
capacity = max_size;
value = new int[max_size];
size = 0;
value[0] = 100010; //下标从1开始存元素,value[0]作为哨兵
}
~heapstruct()
{
delete[]value;
size = 0;
}
bool isfull()
{
return size == capacity ? true : false;
}
bool isempty()
{
return size == 0 ? true : false;
}
//由于一个个插入节点时间复杂度为O(nlogn),则先读入,再采用删除的思想进行排序就可以了
void insert(int x)
{
int i;
if (isfull())
{
cout << "the heapstruct is full" << endl;
return;
}
i = ++size; //i指向堆中最后一个元素,同时数量+1
for (; value[i / 2] < x; i /= 2) //调节节点值的位置,使插入元素后堆的有序性仍然成立,此时这里value[0]起了一个哨兵的作用,它比堆中任何一个值都大,确定了堆顶的位置
value[i] = value[i / 2]; //这里是最大堆的实现,若父节点小于子节点,则将父节点往下移
value[i] = x; //找到合适的位置,将元素插入
}
int deleteMax() //取出并删除最大值
{
int father, son;
if (isempty())
{
cout << "the heapstruct is empty" << endl;
return 0;
}
int max_value = value[1];
int tem = value[size--]; //先取出最后一个元素放在堆顶的位置,再将size-1
for (father = 1; father * 2 <= size; father = son) //假设先将最后一个元素放在根节点,再从根节点开始给它找个合适位置放
{ //father * 2 <= size 看该节点是否有左儿子
son = father * 2;
if (son != size /*一定有右儿子*/ && value[son] < value[son + 1]) //将son始终指向值大的那个儿子
son++;
if (tem >= value[son])break; //找到合适位置
else value[father] = value[son];
}
value[father] = tem;
return max_value;
}
};
期末考试快来了,根本不想复习,索性就写了些数据结构QAQ