C++ 数据结构 、排序算法、BFS/DFS

本文详细介绍了C++中的数据结构,包括vector、queue、stack、string、List、Array、Binary tree、Graph以及排序算法。在二叉树部分,涵盖了不同类型的二叉树如满二叉树、完全二叉树、平衡二叉树和红黑树。此外,文章还讨论了图的邻接矩阵和邻接表,并讲解了广度优先搜索(BFS)和深度优先搜索(DFS)。最后,简要概述了各种排序算法,如冒泡、选择、插入、希尔、归并、快速、堆和基数排序。
摘要由CSDN通过智能技术生成

数据结构

0、vector

        理解为动态数组,作为一个动态数组,vector 有一个指针指向一片连续的内存空间,但是这片空间不是无限的,当内存装不下数据时,系统会自动申请一片更大的空间把原来的数据拷贝过去,释放原来的内存空间。 vector 的内存非常重要,一旦内存重新配置,与之相关的所有指针、迭代器都会失效,而且配置内存非常耗时。

一、queue ,deque(双端队列)
  #include<queue>即可使用队列类:

(1). push
(2). pop
(3). size
(4). empty()  //判断队列是否为空的,如果为空则返回true
(5). front
(6). back

二、stack:#include<stack>头文件;

1.入栈:如s.push(x);

2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。

3.访问栈顶:如s.top();

4.判断栈空:如s.empty().当栈空时返回true。

5.访问栈中的元素个数,如s.size();

三、string:

 string &insert(int p,const string &s);  //在p位置插入字符串s 
string &replace(int p, int n,const char *s); //删除从p开始的n个字符,然后在p处插入串s 
string &erase(int p, int n);  //删除p开始的n个字符,返回修改后的字符串 
string substr(int pos = 0,int n = npos) const;  //返回pos开始的n个字符组成的字符串 void swap(string &s2);    //交换当前字符串与s2的值 
string &append(const char *s);   //把字符串s连接到当前字符串结尾 
void push_back(char c)   //当前字符串尾部加一个字符c 
const char *data()const;    //返回一个非null终止的c字符数组,data():与c_str()类似,用于string转const char*其中它返回的数组是不以空字符终止, 
const char *c_str()const;    //返回一个以null终止的c字符串,即c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同,用于string转const char*

四、List:List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。

Lst1.assign() 给list赋值 
Lst1.back() 返回最后一个元素 
Lst1.begin() 返回指向第一个元素的迭代器 
Lst1.clear() 删除所有元素 
Lst1.empty() 如果list是空的则返回true 
Lst1.end() 返回末尾的迭代器 
Lst1.erase() 删除一个元素 
Lst1.front() 返回第一个元素 
Lst1.get_allocator() 返回list的配置器 
Lst1.insert() 插入一个元素到list中 
Lst1.max_size() 返回list能容纳的最大元素数量 
Lst1.merge() 合并两个list 
Lst1.pop_back() 删除最后一个元素 
Lst1.pop_front() 删除第一个元素 
Lst1.push_back() 在list的末尾添加一个元素 
Lst1.push_front() 在list的头部添加一个元素 
Lst1.rbegin() 返回指向第一个元素的逆向迭代器 
Lst1.remove() 从list删除元素 
Lst1.remove_if() 按指定条件删除元素 
Lst1.rend() 指向list末尾的逆向迭代器 
Lst1.resize() 改变list的大小 
Lst1.reverse() 把list的元素倒转 
Lst1.size() 返回list中的元素个数 
Lst1.sort() 给list排序 
Lst1.splice() 合并两个list 
Lst1.swap() 交换两个list 
Lst1.unique() 删除list中重复的元素

五、Array

at()Access element 
front()Access first element
back()Access last element

六、Binary tree

1、二叉树分类:


满二叉树:从高到低,除了叶节点外,所以节点左右节点都存在。

完全二叉树:比满二叉树少几个叶节点,从左向右放子节点

平衡二叉树(AVL):空树或者它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是平衡树。

二叉搜索/查找/排序(sort)树:空树或者二叉树的所有节点比他的左子节点大,比他的右子节点小

线索二叉树:在节点的结构中增加了两个数据标志位:int  itag ,rtag

最优二叉树/哈夫曼树(Huffman Tree):若带权路径(WPL = W*L)长度达到最小,称这样的二叉树为最优二叉树;

红黑树(平衡二叉搜索树)不仅是具有二叉搜索树的属性,还具有平衡树的属性,有序且子树差不超过1,颜色规则:根节点和特殊节点(即叶节点下面两个虚无的节点和未填写的节点)是黑的,红节点的左右子节点是黑的,最重要的是对于每个节点,从该节点到子孙叶节点的所有路径包含相同数目的黑节点。

 

七、图 Graph

图的存储结构主要分两种,一种是邻接矩阵(顺序存储结构),一种是邻接表(链式存储结构)。

1.邻接矩阵

    邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边。

                             

从这个矩阵中,很容易知道图中包含的信息:
(1)要判断任意两顶点是否有边无边就很容易了;
(2)要知道某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点;

2. 邻接表

    邻接矩阵是不错的一种图存储结构,但是,对于边数相对顶点较少的图,这种结构存在对存储空间的极大浪费。因此,找到一

数组与链表相结合的存储方法称为邻接表

           

(1)图中顶点用一个一维数组存储,也可以用单链表来存储,不过,数组可以较容易的读取顶点的信息,更加方便。
(2)图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以,用单链表存储,无向图称为顶点vi的边表,有向图则称为顶点vi作为弧尾的出边表。

从图中可以看出,顶点表的各个结点由data和firstedge两个域表示,data是数据域,存储顶点的信息,firstedge是指针域,指向边表的第一个结点,即此顶点的第一个邻接点。

边表结点由adjvex和next两个域组成。adjvex是邻接点域,存储某顶点的邻接点在顶点表中的下标,next则存储指向边表中下一个结点的指针。

3、根据搜索路径的不同,我们可以将遍历图的方法分为两种:广度优先搜索和深度优先搜索

              https://blog.csdn.net/weixin_40953222/article/details/80544928

3.1 广度优先搜索

    广度优先搜索类似于树的层次遍历过程,需要借助一个队列来实现。

搜索过程如下:

(1).准备工作:创建一个visited数组,用来记录已被访问过的顶点;创建一个队列,用来存放每一层的顶点;初始化图G。

(2).从图中的v0开始访问,将的visited[v0]数组的值设置为true,同时将v0入队。

(3).只要队列不空,则重复如下操作:    (1)队头顶点u出队。    (2)依次检查u的所有邻接顶点w,若visited[w]的值为false,则访问w,并将visited[w]置为true,同时将w入队。
 

                                 

3.2、深度优先搜索

深度优先搜索类似于树的先序遍历。

搜索过程:创建一个visited数组,用于记录所有被访问过的顶点。

                                             

 

八、HashTable

        建立Hash 函数,

       处理冲突的方法:链地址法,将每个hash地址作为一个指针,指向一个链表。

九、C++ 的容器类型可以分为顺序容器和关联容器两大类。顺序容器我们前面的使用已经介绍了 vector、list 和 deque;
关联容器支持通过键值来高效的查找和读取元素,这是它和顺序容器最大的区别。两种基本的关联容器类型是 map 和 set,衍生类型有 multimap 和 multiset。  
       Map 是 STL 的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字 key 只能在map中出现一次,第二个可能称为该关键字的值data)的数据处理能力,由于这个特性,它完全有可能在我们处理一对一数据的时候,在编程上提供快速通道。

十、排序算法:

每个算法用一句话总结:

1、冒泡排序:

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  • 针对所有的元素重复以上的步骤,除了最后一个 :len - 1 - i
 for (var i = 0; i < len - 1; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j+1]) {        // 相邻元素两两对比
                var temp = arr[j+1];        // 元素交换
                arr[j+1] = arr[j];
                arr[j] = temp;
            } } }

2、选择排序(Selection Sort)

工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。设置一个最小下标 : minIndex = i;

for (var i = 0; i < len - 1; i++) {
        minIndex = i;
        for (var j = i + 1; j < len; j++) {
            if (arr[j] < arr[minIndex]) {     // 寻找最小的数
                minIndex = j;                 // 将最小数的索引保存
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
       }

3、插入排序(Insertion Sort)

工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

4、希尔排序(Shell Sort)

是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素

5、归并排序(Merge Sort)

采用分治法(Divide and Conquer)。长度为n的输入序列分成两个长度为n/2的子序列;对这两个子序列分别采用归并排序;对这两个子序列分别采用归并排序;

6、快速排序(Quick Sort)

使用分治法来把一个串(list)分为两个子串(sub-lists),使用分治法来把一个串(list)分为两个子串(sub-lists)。

7、堆排序(Heap Sort)

堆排序(Heapsort)指利用堆这种数据结构所设计的一种排序算法。

8、计数排序(Counting Sort)

计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。

9、桶排序(Bucket Sort)

      桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序。

10、基数排序(Radix Sort)



   


 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值