数据结构与算法——数据结构知识归纳
C++中,内存分为5个区:堆、栈、自由存储区、全局/静态存储区和常量存储区。
- 栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区。通常存放局部变量、函数参数等。
- 堆:是由new分配的内存块,由程序员释放(编译器不管),一般一个new与一个delete对应,一个new[]与一个delete[]对应。如果程序员没有释放掉,资源将由操作系统在程序结束后自动回收。
- 自由存储区:是由malloc等分配的内存块,和堆十分相似,用free来释放。
- 全局/静态存储区:全局变量和静态变量被分配到同一块内存中(在C语言中,全局变量又分为初始化的和未初始化的,C++中没有这一区分)。
- 常量存储区:这是一块特殊存储区,里边存放常量,不允许修改。
(注意:堆和自由存储区其实不过是同一块区域,new底层实现代码中调用了malloc,new可以看成是malloc智能化的高级版本)
一、 堆与栈
1.1 堆与栈的区别
- 管理方式:堆中资源由程序员控制(容易产生memory leak), 栈资源由编译器自动管理,无需手工控制。
- 系统响应:对于堆,应知道系统有一个记录空闲内存地址的链表,当系统收到程序申请时,遍历该链表,寻找第一个空间大于申请空间的堆结点,删 除空闲结点链表中的该结点,并将该结点空间分配给程序(大多数系统会在这块内存空间首地址记录本次分配的大小,这样delete才能正确释放本内存 空间,另外系统会将多余的部分重新放入空闲链表中)。对于栈,只要栈的剩余空间大于所申请空间,系统为程序提供内存,否则报异常提示栈出。
- 空间大小: 堆是不连续的内存区域(因为系统是用链表来存储空闲内存地址,自然不是连续的),堆大小受限于计算机系统中有效的虚拟内存(32bit 系统理论上是4G),所以堆的空间比较灵活,比较大。栈是一块连续的内存区域,大小是操作系统预定好的,windows下栈大小是2M(也有是1M,在 编译时确定,VC中可设置)。
- 碎片问题:对于堆,频繁的new/delete会造成大量碎片,使程序效率降低。 对于栈,它是一个先进后出的队列,进出一一对应,不会产生碎片。
- 生长方向:堆向上,向高地址方向增长。栈向下,向低地址方向增长。
- 分配方式: 堆都是动态分配(没有静态分配的堆)。栈有静态分配和动态分配,静态分配由编译器完成(如局部变量分配),动态分配由alloca函数分配,但栈的动态分配的资源由编译器进行释放,无需程序员实现。
- 分配效率:堆由C/C++函数库提供,机制很复杂。所以堆的效率比栈低很多。栈是极其系统提供的数据结构,计算机在底层对栈提供支持,分配专门寄存器存放栈地址,栈操作有专门指令。
1.2 程序操作
- 栈(stack):先进后出(FILO)
stack<int> stk;
stk.empty() 如果栈为空返回true,否则返回false;
stk.size() 返回栈内元素的大小;
stk.pop() 从栈顶弹出一个成员;
stk.push() 向栈内压入一个成员;
stk.top() 返回栈顶,但不删除成员;
- 队列(queue):先进先出(FIFO)
queue<int> que;
que.empty() 如果队列为空返回true,否则返回false;
que.size() 返回队列内元素的大小;
que.pop() 从队列弹出一个成员;
que.push() 向队列压入一个成员;
que.front() 返回到队首,但不删除成员;
que.back() 返回到队尾,但不删除成员;
- 堆(heap):二叉树
树是一些节点的集合,节点之间用边链接,节点之间不能有环路。上层的节点称为父节点,下层节点称为子节点。最上层的节点称为根节点。
二叉树是特殊的树。对于每个节点而言,与之直接相连的子节点不能超过两个(可以为0)。左边的子节点称为左子树,右边的子节点称为右子树。如下图就是一颗二叉树:
与树相关的一些概念:
- 树叶(叶子节点):没有任何子节点的节点。
- 深度:对于任意节点N,其深度指的是从根节点到N的唯一路径的长。根的深度为0。深度最深的叶子节点的深度为树的深度。可以理解为:树根是一个入口,离树根越远,就越深。如上图:A、B、C的深度为1,D、E的深度为2。
- 高:对于任意节点N,从N到一片树叶的最远路径的长为N的高度(只可以从从上到下不能经过从下到上的节点),树叶的高为0。树的高为根的高。如上图,根的高度为2,A的高度为1,其他节点高度为0。
#include <algorithm>
make_heap: 根据指定的迭代器区间以及一个可选的比较函数,来创建一个heap. O(N)
push_heap: 把指定区间的最后一个元素插入到heap中. O(logN)
pop_heap: 弹出heap顶元素, 将其放置于区间末尾. O(logN)
sort_heap:堆排序算法,通常通过反复调用pop_heap来实现. N*O(logN)针。c++11
is_heap: 判断给定区间是否是一个heap. O(N)
is_heap_until: 找出区间中第一个不满足heap条件的位置. O(N)
二、 链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。根据节点包含内容不同可以分为单向链表和双向链表。
2.1 代码实现链表
单向链表的节点:
- 数据域:用于存储数据元素的值。
- 指针域(链域):用于存储下一个结点地址或者说指向其直接后继结点的指针。
struct Node{int value;Node * next;};
双向链表的节点:
- 数据域:用于存储数据元素的值。
- 左指针域(左链域):用于存储上一个结点地址或者说指向其直接前继结点的指针。
- 右指针域(右链域):用于存储下一个结点地址或者说指向其直接后继结点的指针。
struct DNode{int value;DNode * left;DNode * right;};
数据域:用于存储数据元素的值。
指针域(链域):用于存储下一个结点地址或者说指向其直接后继结点的指针。常用操作:
//插入节点(单向链表)
//p节点后插入值为i的节点
void insertNode(Node *p, int i){Node* node = new Node;node->value = i;node->next = p->next;p->next = node;
}//删除节点(单向链表)
void deleteNode(Node *p){p->value = p->next->value;p->next = p->next->next;
}
2.2 使用stl的List库实现链表
//创建链表
list<int> lst1; //创建空list
list<int> lst2(5); //创建含有5个元素的list
list<int> lst3(lst2); //使用lst2初始化
list<int> lst4(lst2.begin(),lst2.end()); //使用lst2初始化//基本操作
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中重复的元素
参考
https://blog.csdn.net/u013846293/article/details/79410293?utm_source=blogxgwz1
堆和栈参考:https://blog.csdn.net/yangyong0717/article/details/78001609
链表参考:https://www.cnblogs.com/byonecry/p/4458821.html
二叉树参考:https://blog.csdn.net/u014182411/article/details/69831492/
https://blog.csdn.net/flyyufenfei/article/details/78175511
数据结构与算法——数据结构知识归纳相关推荐
- CAUC数据结构与算法期末复习归纳(二)
CAUC数据结构与算法期末复习归纳(二) 二叉树 二叉树的周游 二叉树的抽象数据类型 深度优先周游二叉树或其子树 广度优先周游二叉树 二叉树的存储结构 二叉树的链式存储结构 二叉搜索树 二叉搜索树的性 ...
- 【Java面试高频问题】Java数据结构和算法基础知识汇总
文章目录 Java数据结构和算法基础知识 一.Java数据结构 1. 线性结构:数组.队列.链表和栈 1.1 数组(Array) 1.2 稀疏数组 1.3 队列(Queue) 1.4 链表(Linke ...
- 【数据结构与算法 - 数据结构基础】什么是数据结构?
[数据结构与算法 - 数据结构基础]什么是数据结构? 文章目录 [数据结构与算法 - 数据结构基础]什么是数据结构? 1 数据结构包含的三个方面 1.1 数据的逻辑结构 1.1.1 线性结构 数组[A ...
- 《数据结构与算法》知识小结
数据结构在研究的其实就是逻辑结构,其中包括线性结构.树结构.图结构. 线性结构:结构中的数据元素之间存在着一对一的线性关系. 树结构:结构中的数据元素之间存在着一对多的层次关系. 图结构:结构中的数据 ...
- 数据结构与算法基础知识集锦
程序设计 = 数据结构 + 算法 数据结构分为逻辑结构与物理结构 逻辑结构:是指数据对象中数据元素之间的相互关系:物理结构:是指数据的逻辑结构在计算机中的存储形式. 逻辑结构可以分为:集合结构.线性结 ...
- 1.数据结构与算法 基础知识
文章目录 数据结构与算法 (Python 版) 知识点一 : 算法 概念 知识点二 : 时间复杂度 知识点三 : 空间复杂度 知识点四 : 递归 知识点五 : 递归 汉诺塔问题 1.题目 2.思路 3 ...
- 数据结构与算法之排序(归纳总结三)
选择排序的基本思想是:每一趟从n-i+1 (i=1,2,-,n)个元素中选取一个关键字最小的元素作为有序序列中第i个元素.本节在介绍简单选择排序的基础上,给出了对其进行改进的算法堆排序. 1.简单选择 ...
- 数据结构与算法-----数据结构-----2-3-4树以及外部存储
树 转载于:https://www.cnblogs.com/lxrm/p/6440248.html
- Go语言-数据结构与算法
go语言之专业数据结构与算法 3.golang实现数组结构 code\ArrayList\ArrayList.go package ArrayListimport ("errors" ...
最新文章
- LookupError: unknown encoding: uft-8
- 操作系统学习:内存分页与中断
- Eclipse安装SVN最新版插件
- vSphere vCenter 4.0 安装图解
- Android仿IOS的AssistiveTouch的控件EasyTouch实现
- Wannafly挑战赛23F-计数【原根,矩阵树定理,拉格朗日插值】
- gdb学习(二)[第二版]
- edit box小技巧
- spring Annotation 组件注入
- 数据库MySQL学习教程(带你零基础入门MySQL)
- 【数学建模暑期培训】CUMCM历年题分类 2000-2021年数模国赛赛题及求解模型
- 白杨SEO:推广与运营有什么区别和相同?推广如何转运营?
- SYSAUX表空间占用过大情况下的处理(AWR信息过多)
- 如何制作微信二维码指纹扫描图片
- A4纸张缩印怎么只打印一半A4纸的内容
- pg_repack安装及使用
- Dell EMC VxRail超融合节点升级混合云软件
- whm面板降mysql_WHMCS与Cpanel/WHM面板整合方法-Cpanel/WHM管理使用教程 | 麦田一棵葱...
- 游戏设计艺术 第2版 第30章 读书笔记
- ZigBee的软件抓包分析