一、快排:
#include <algorithm>
using namespace std;
bool compare(int a,int b)
{
return a<b; //升序排列,如果改为return a>b,则为降序
}
sort(a,a+n,cmp);
先按x升序排序,若x值相等则按y升序排:
int cmp( const NODE &a, const NODE &b )
{
if( a.x < b.x )
return 1;
else if( a.x == b.x )
{
if( a.y < b.y )
return 1;
else
return 0;
}
else
return 0;
}
sort(a,a+n,cmp);
二、树的相关操作:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char data;
struct node *left;
struct node *right;
};
char st1[50];
char st2[50];
1、按先序遍历输入的字符序列:
struct node * creat()
{
char ch = s[l++];
struct node *root;
if(ch==',')
{
return NULL;
}
else
{
root = (struct node *)malloc(sizeof(struct node));
root->data = ch;
root->left = creat();
root->right = creat();
}
return root;
}
2.已知前序遍历和中序遍历,求二叉树。
struct node * creat(char *st1, char *st2, int n)
{
if(n<=0) return NULL;
struct node *root;
root = (struct node *)malloc(sizeof(struct node));
root->data = st1[0];
char *i;
for(i=st2; i<st2+n; i++)
{
if(*i==*st1)
break;
}
int x = i-st2+1;
root->left = creat(st1+1, st2, x-1);
root->right = creat(st1+x, st2+x, n-x);
return root;
}
3.已知中序遍历和后序遍历,求二叉树。
struct node *creat(char *st1, char *st2, int n)
{
if(n<=0)
return NULL;
struct node *root;
root = (struct node *)malloc(sizeof(struct node));
root->data = *(st2+n-1);
char *i;
for(i=st1; i<st1+n; i++)
{
if(*i==*(st2+n-1))
{
break;
}
}
int x = i-st1+1;
root->left = creat(st1, st2, x-1);
root->right = creat(st1+x, st2+x-1, n-x);
return root;
}
4.层次遍历:
void level(struct node *root)
{
struct node *a[60];
int x = 0;
int y = 1;
a[0] = root;
while(x<y)
{
if(a[x])
{
printf("%c", a[x]->data);
a[y++] = a[x]->left;
a[y++] = a[x]->right;
}
x++;
}
}
5、求二叉树的高度
int deep(struct node *root)
{
if(root==NULL) return 0;
if(root->left==NULL && root->right==NULL) return 1;
int ld = deep(root->left);
int rd = deep(root->right);
if(ld>rd) return 1+ld;
else if(ld<=rd) return 1+rd;
}
6、求叶子数。
int leaf(struct node *root)
{
if(root==NULL) return 0;
if(root->left == NULL && root->right == NULL)
return 1;
else
return leaf(root->left)+leaf(root->right);
}
7、按从上到下从左到右的顺序输出二叉树的叶子结点。
void leaf(struct node *root)
{
struct node *a[N];
int x = 0;
int y = 1;
a[0] = root;
while(x<y)
{
if(a[x])
{
if(a[x]->left==NULL && a[x]->right==NULL)
printf("%c", a[x]->data);
a[y++] = a[x]->left;
a[y++] = a[x]->right;
}
x++;
}
}
8、后序输出:
void after(struct node *root)
{
if(root)
{
after(root->left);
after(root->right);
printf("%c", root->data);
}
}
三、深搜和广搜:
1、邻接矩阵:
void dfs(int i)
{
int j;
visit[i] = 1;
for(j=0; j<n; j++)
{
if(visit[j]==0 && map[i][j]==1)
{
visit[j] = 1;
dfs(j);
}
}
}
void bfs(int n, int x)
{
queue <int> q;
p = 0;
ans[p++] = x;
visit[x] = 1;
q.push(x);
while(!q.empty())
{
int f = q.front();
q.pop();
for(int i=0; i<n; i++)
{
if(visit[i]==0 &&map[f][i]==1)
{
q.push(i);
ans[p++] = i;
visit[i] = 1;
}
}
}
}
2、与邻接表相似的vector:
头文件:#include <vector>
建立:struct node
{
int to;
int w;//可以附加其他属性,比如权值;
} f;
vector <node> g[maxn];
初始化:
void initvector()
{
for(int i=0; i<=k; i++)
{
g[i].clear();
}
memset(visit, 0, sizeof(visit));
}
输入:
while(m--)
{
scanf("%d%d", &u, &v);
f.to = v;
g[u].push_back(f);
f.to = u;
g[v].push_back(f);
}
dfs:
void dfs(int start)
{
visit[start] = 1;
printf("%d ", start);
for(int i=0; i<g[start].size(); i++)
{
if(visit[g[start][i].to]==0)
{
dfs(g[start][i].to);
}
}
}
bfs:
void bfs(int start)
{
int j;
visit[start] = 1;
queue <int> q;
printf("%d ",start);
q.push(start);
while(!q.empty())
{
j = q.front();
q.pop();
for(int i=0; i<g[j].size(); i++)
{
if(visit[g[j][i].to]==0)
{
visit[g[j][i].to] = 1;
printf("%d ", g[j][i].to);
q.push(g[j][i].to);
}
}
}
}
四、KMP:
void getnext(int len2)//求next数组。
{
int i=0, j=-1 ;
next[0] = -1;
while(i<len2)
{
if(j==-1 || st2[i]==st2[j])
{
i++;
j++;
next[i] = j;
}
else
{
j = next[j];
}
}
}
int kmp(int len1, int len2)//kmp算法
{
int i=0;
int j=0;
while(i<len1 && j<len2)
{
if(j==-1 || st1[i]==st2[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if(j>=len2)
return i-len2+1;
else
return -1;
}
五、并查集:
int find(int x)
{
int r, j;
r = x;
while(pre[r]!=r)
{
r = pre[r];
}
int l;
l = x;
while(l!=r)
{
j = pre[l];
pre[l] = r;
l = j;
}
return r;
}
void join(int x, int y)
{
int fx = find(x);
int fy = find(y);
if(fx!=fy)
{
pre[fy] = fx;
}
}
五、栈和队列以及常用C++函数:
1.Stack
top()返回栈顶元素,并不移除这个元素
empty()如果栈空返回true,否则false
size()栈的大小
void push()插入元素到栈顶
void pop()移除栈顶元素
2.queue
empty()判空
front()返回队头元素
pop()删除对头元素
back()返回队尾元素
push()在队尾加入元素
size()大小
3、不定长数组:vector
vector就是一个不定长数组。
它把一些常用操作“封装”在了vector类型内部。
基本操作
(1)头文件#include<vector>;
(2)创建vector对象,vector<int> vec;
(3)尾部插入数字:vec.push_back(a);
(4)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的。
(5)使用迭代器访问元素.
<span style="font-size:18px;">vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++)
cout<<*it<<endl;</span>
(6)插入元素:vec.insert(vec.begin()+i,a);在第i个元素后面插入a;
(7)删除元素:vec.erase(vec.begin()+2);删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
(8)向量大小:vec.size();
向尾部添加元素:vec.push_back();
删除最后一个元素:vec.pop_back);
(9)清空:vec.clear() //清空之后,vec.size()为0
vector<Edge>G[maxn];
void init()
{
for(int i=0;i<=n;i++)
G[i].clear();
memset(vis,0,sizeof(vis));
}
c.back() // 传回最后一个数据,不检查这个数据是否存在。
c.capacity() // 返回容器中数据个数。
c.empty() // 判断容器是否为空。
c.end() // 指向迭代器中末端元素的下一个,指向一个不存在元素。
c.front() // 传回第一个数据。
c.insert(pos,elem) // 在pos位置插入一个elem拷贝,传回新数据位置。
c.insert(pos,n,elem) // 在pos位置插入n个elem数据。无返回值。
c.insert(pos,beg,end) // 在pos位置插入在[beg,end)区间的数据。无返回值。
c.max_size() // 返回容器中最大数据的数量。
c.pop_back() // 删除最后一个数据。
c.push_back(elem) // 在尾部加入一个数据。
c.rbegin() // 传回一个逆向队列的第一个数据。
c.rend() // 传回一个逆向队列的最后一个数据的下一个位置。
c.resize(num) // 重新指定队列的长度。
c.reserve() // 保留适当的容量。
c.size() // 返回容器中实际数据的个数。
c1.swap(c2)
swap(c1,c2) // 将c1和c2元素互换。同上操作。
4.map的基本操作函数:
#include <stdio.h>
C++ Maps是一种关联式容器,包含“关键字/值”对
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
erase() 删除一个元素
find() 查找一个元素
insert() 插入元素
max_size() 返回可以容纳的最大元素个数
size() 返回map中元素的个数
swap() 交换两个map
六、图论(最短路问题):
Dijkstra算法:
int dijkstra(int n, int endd)
{
//初始化v[0]到v[i]的距离
for(int i=1;i<=n;i++)
dis[i] = mapp[0][i];
vis[0]=1;//标记v[0]点
for(int i = 1; i <= n; i++)
{
//查找最近点
int minn = MAX,k = 0;
for(int j = 0; j <= n; j++)
if(!vis[mapp] && dis[j] < minn)
{
minn = dis[mapp];
k = j;
}
vis[k] = 1;//标记查找到的最近点
//判断是直接v[0]连接v[j]短,还是经过v[k]连接v[j]更短
for(int j = 1; j <= n; j++)
if(!vis[j] && minn+mapp[k][j] < dis[j])
d[j] = minn+mapp[k][j];
}
return dis[endd];//endd为所求终点。
}
struct node
{
int u, v, w;
node(int uu, int vv, int ww):u(uu), v(vv), w(ww) {}
};
vector <node> mp[maxn];
SPFA算法:
void spfa_bfs(int start, int n)
{
memset(visit, 0, sizeof(visit));
memset(cnt, 0, sizeof(cnt));
queue <int> q;
for(int i=0; i<=n; i++)
{
dis[i] = MAX;
}
dis[start] = 0;
q.push(start);
while(!q.empty())
{
int u = q.front();
q.pop();
visit[u] = 0;
for(int i=0; i<mp[u].size(); i++)
{
node &e = mp[u][i];
if(dis[u]<MAX && dis[e.v]>dis[u]+e.w)
{
dis[e.v] = dis[u] + e.w;
if(visit[e.v]==0)
{
q.push(e.v);
visit[e.v] = 1;
}
if(cnt[e.v]++>n)//判断负环;BFS版的判断标准:是否存在某个节点入队超过n次 ;
{
flag = 1;
return ;
}
}
}
}
}
DFS:
void dfs(int u)
{
cir[u] = 1;
for(int i=0; i<mp[u].size(); i++)
{
if(!cir[mp[u][i].v])
dfs(mp[u][i].v);
}
}
void spfa_dfs(int start, int n)
{
memset(visit, 0, sizeof(visit));
memset(cnt, 0, sizeof(cnt));
memset(cir, 0, sizeof(cir));
queue <int> q;
for(int i=0; i<=n; i++)
{
dis[i] = MAX;
}
dis[start] = 0;
cnt[start] = 1;
q.push(start);
while(!q.empty())
{
int u = q.front();
q.pop();
visit[u] = 0;
for(int i=0; i<mp[u].size(); i++)
{
node &e = mp[u][i];
if(cir[e.v])
continue;
if(dis[u]<MAX && dis[e.v]>dis[u]+e.w)
{
dis[e.v] = dis[u] + e.w;
if(visit[e.v]==0)
{
q.push(e.v);
visit[e.v] = 1;
cnt[e.v]++;
if(cnt[e.v]>n)
dfs(e.v);
}
}
}
}
}
FLoy算法:
void floy(int x, int y, int n)
{
int i, j, k;
for(k=0; k<n; k++)
{
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(d[i][j]<MAX && d[k][j]<MAX)
{
d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
}
}
}
}
}