C++常用数据结构

常用的数据结构:

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:哈希 这个用的好像比较少。不说了吧


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值