常用的数据结构:
1 数组
数组是一种聚合数据类型。可以用memset(); sort(a,a+n,cmp); 如果是char [],还可以strlen();得到长度。
同时,c++语言风格的int *a =new int[12];删除的时候用delete []a ;二维数组的时候如下的风格:
int**a = new int *[12];
for(int i=0;i<12;i++)
{
a[i]= new int[12];
}
同时delete 要对每个都delete 如下的格式 delete[] a[i];
如果用c语言的风格,格式如下:
int *a = (int *)malloc(sizeof(a)*10);
free(a);
这样的一个函数释放,二维数组也是如此。
2 栈
栈是一种特殊的结构。主要由顺序和链式实现栈的操作。栈的基本操作代码如下;
可以实现的数据类型有。
应用的题目主要有:栈的出栈顺序等
3 队列
队列的基本操作如下:
FIFO queue:
Emplace 和swap是c++ 11 才支持的。
// queue::emplace
#include <iostream> // std::cin, std::cout
#include <queue> // std::queue
#include <string> // std::string, std::getline(string)
int main ()
{
std::queue<std::string>myqueue;
myqueue.emplace ("Firstsentence");
myqueue.emplace ("Secondsentence");
std::cout << "myqueuecontains:\n";
while (!myqueue.empty())
{
std::cout << myqueue.front() << '\n';
myqueue.pop();
}
return 0;
}
// queue::emplace #include <iostream> // std::cin, std::cout #include <queue> // std::queue #include <string> // std::string, std::getline(string) int main () { std::queue<std::string> myqueue; myqueue.emplace ("First sentence"); myqueue.emplace ("Second sentence"); std::cout << "myqueue contains:\n"; while (!myqueue.empty()) { std::cout << myqueue.front() << '\n'; myqueue.pop(); } return 0; }
// queue::emplace #include <iostream> // std::cin, std::cout #include <queue> // std::queue #include <string> // std::string, std::getline(string) int main () { std::queue<std::string> myqueue; myqueue.emplace ("First sentence"); myqueue.emplace ("Second sentence"); std::cout << "myqueue contains:\n"; while (!myqueue.empty()) { std::cout << myqueue.front() << '\n'; myqueue.pop(); } return 0; }
还有就是优先队列。在前面的博客中也讲到了,priority_queue<int , vector<int > , cmp>
或者自己重载了<符号,不需要用cmp或者是std::greater<int> 或者是std::less<int>这种类型。
Greater是一个类。
实现如下:
template <class T> struct greater { bool operator() (const T& x, const T& y) const {return x>y;} typedef T first_argument_type; typedef T second_argument_type; typedef bool result_type; }; template <class T> struct greater { bool operator() (const T& x, const T& y) const {return x>y;} typedef T first_argument_type; typedef T second_argument_type; typedef bool result_type; };
4 链表
链表包括指针和数据两部分组成。主要用处不大,可以在别的数据结构中用到。有单向和双向链表的说法。
5 树
树的知识点非常多。
有二叉树,二叉搜索树。叶子节点,父节点,兄弟这些术语就不介绍了。还有就是path 路径,路径的长度。一个节点的深度,树的深度(dfs),宽度(bfs)
森林的宽度这些东西,可以出的题目很多。
树的构造,3种遍历(递归和非递归的遍历),两种遍历构造树
树的基本数据结构:
typedef int T;
struct BinaryNode{
Telement;
BinaryNode *left, *right;
BinaryNode(T d, BinaryNode *l=NULL, BinaryNode* r=NULL):element(d),left(l), right(r) {};
};
typedef int T;
struct BinaryNode{
Telement;
BinaryNode *left, *right;
BinaryNode(T d, BinaryNode *l=NULL, BinaryNode* r=NULL):element(d),left(l), right(r) {};
};
中序:用栈存储
Traverse the tree p (which points to theroot):
a) If p!= NULL, push it into stack;
b) Traveser p->left, that is p = p->left;
c) If p==NULL, pop out the root, visit the root, and then traverse theright subtree root->right, that is
p = root->right;
Repeat the process until the stack isempty。
void nonRecursiveInorder(BinaryNode *root,void(*visit)(T &x))
stack<BinaryNode*> s;
p=root;//p points the current root of traversal
while(p|| !s.empty())
if(p)
{// push root into stack and traverse the left subtree
raverse the left subtree
s.push(p);
p=p->left;
}
else{
//no left subtree, pop out the root, visit the root
//and traverse the right subtree
p = s.top();
visit(p->data)) ;
p=p->right;
}
}
}
s.push(p);
p=p->left;
}
else{
//no left subtree, pop out the root, visit the root
//and traverse the right subtree
p = s.top();
visit(p->data)) ;
p=p->right;
}
}
}
还有层次遍历:也是用栈存储起来数据。
对于BST树
各种操作如下;
AVL树比较复杂,这里不讲了。求小伙伴们原谅。
6:图
专门有图论这一门课来讲。所以图的应用范围非常广。主要的算法也很多,求最大二分匹配问题,最大流最小割等问题。
图的表示有两种:邻接矩阵(空间大,时间复杂度多,用在稠密图)和邻接表。
拓扑排序中有一道例题:http:soj.me/1509
工作调度问题
Bfs找最短路
Dfs找强连通分支和拓扑排序
找最短路可以用dijkstra算法,也是贪心算法
Dijkstra(G, s):
Input: s is thesource
Output: mark everyvertex with the shortest distance froms.
for every vertex v {
set v (F, weight(s,v))
}
set s(T, 0);
while ( there is a vertex with (F, _)) {
find the vertex v with thesmallest distvamong (F, dist)
set v(T, distv)
for every w(F, dist) adjacent tov{
if(distv + weight(v,w) <dist)
set w(F, distv + weight(v,w))
}
}
找最小支撑树 MST 用的方法是prim 和krusal
DFS算法:
7:堆
是一种特殊的树形数据结构。最大堆或者最小堆,概念上是比自己的子代都大或者都小,同时进行编号,在删除根节点的时候,把最大编号的那个点放上去,之后再调整堆的顺序。
#include<iostream> // std::cout
#include<algorithm> // std::make_heap,std::pop_heap, std::push_heap, std::sort_heap
#include<vector> // std::vector
int main () {
int myints[] = {10,20,30,5,15};
std::vector<int> v(myints,myints+5);//对vector初始化这样甚好
std::make_heap (v.begin(),v.end());
std::cout << "initial maxheap : " << v.front()<< '\n';
std::pop_heap (v.begin(),v.end());
v.pop_back();
std::cout << "max heap after pop :" << v.front() << '\n';
v.push_back(99);
std::push_heap (v.begin(),v.end());
std::cout << "max heap after push:" << v.front() << '\n';
std::sort_heap (v.begin(),v.end());
std::cout << "final sorted range:";
for (unsigned i=0; i<v.size(); i++)
std::cout << ' ' << v[i];
std::cout << '\n';
system("pause");
return 0;
}
也就是说把vector<int>v放在了heap 中,并且进行了make_heap(); pop_heap(); v.push(); push_heap(), sort_heap(v.begin(),v.end());之后v变成了最大堆维护。
8:哈希 这个用的好像比较少。不说了吧