学习笔记 - 数据结构

一、常用的数据结构
(1)线性数据结构:元素之间一般存在元素之间存在一对一关系,是最常用的一类数据结构,典型的有:数组、栈、队列和线性表
(2)树形结构:结点间具有层次关系,每一层的一个结点能且只能和上一层的一个结点相关,但同时可以和下一层的多个结点相关,称为“一对多”关系,常见类型有:树、堆
(3)图形结构:在图形结构中,允许多个结点之间相关,称为“多对多”关系

1、线性数据结构:典型的有:数组、栈、队列和线性表
(1)数组和链表
a、数组:存放着一组相同类型的数据,需要预先指定数组的长度,有一维数组、二维数组、多维数组等
b、链表:链表是C语言中一种应用广泛的结构,它采用动态分配内存的形式实现,用一组任意的存储单元存放数据元素链表的,一般为每个元素增设指针域,用来指向后继元素
c、数组和链表的区别:
从逻辑结构来看:数组必须事先定义固定的长度,不能适应数据动态地增减的情况;链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项(数组中插入、删除数据项时,需要移动其它数据项)
从内存存储来看:(静态)数组从栈中分配空间(用NEW创建的在堆中), 对于程序员方便快速,但是自由度小;链表从堆中分配空间, 自由度大但是申请管理比较麻烦
从访问方式来看:数组在内存中是连续存储的,因此,可以利用下标索引进行随机访问;链表是链式存储结构,在访问元素的时候只能通过线性的方式由前到后顺序访问,所以访问效率比数组要低
 
(2)栈、队列和线性表:可采用顺序存储和链式存储的方法进行存储
顺序存储:借助数据元素在存储空间中的相对位置来表示元素之间的逻辑关系
链式存储:借助表示数据元素存储地址的指针表示元素之间的逻辑关系
a、栈:只允许在序列末端进行操作,栈的操作只能在栈顶进行,一般栈又被称为后进先出或先进后出的线性结构
    顺序栈:采用顺序存储结构的栈称为顺序栈,即需要用一片地址连续的空间来存储栈的元素
链栈:采用链式存储结构的栈称为链栈:
队列:只允许在序列两端进行操作,一般队列也被称为先进先出的线性结构
    循环队列:采用顺序存储结构的队列,需要按队列可能的最大长度分配存储空空
链队列:采用链式存储结构的队列称为链队列,一般需要设置头尾指针只是链表的头尾结点

树形结构:结点间具有层次关系,每一层的一个结点能且只能和上一层的一个结点相关,但同时可以和下一层的多个结点相关,称为“一对多”关系,常见类型有:树、堆
(1)二叉树:二叉树是一种递归数据结构,是含有n(n>=0)个结点的有限集合,二叉树具有以下特点:
二叉树可以是空树;二叉树的每个结点都恰好有两棵子树,其中一个或两个可能为空;二叉树中每个结点的左、右子树的位置不能颠倒,若改变两者的位置,就成为另一棵二叉树
 
(2)完全二叉树:从根起,自上而下,自左而右,给满二叉树的每个结点从1到n连续编号,如果每个结点都与深度为k的满二叉树中编号从1至n的结点一一对应,则称为完全二叉树
a、采用顺序存储结构:用一维数组存储完全二叉树,结点的编号对于与结点的下标(如根为1,则根的左孩子为2*i=2*1=2,右孩子为2*i+1=2*1+1=2)

3、图形结构:在图形结构中,允许多个结点之间相关,称为“多对多”关系,可分为有向图和无向图

数组与链表的优缺点和区别
概述
  数组 是将元素在内存中 连续存放 ,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要 快速访问数据,很少插入和删除元素,就应该用数组。
  链表 中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存储 数据元素 的 数据域,另一个是存储下一个结点地址的 指针。 
  如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表 数据结构 就非常简单了,只要修改元素中的指针就可以了。如果应用需要 经常插入和删除元素你就需要用链表
内存存储区别
数组从 中分配空间, 对于程序员方便快速,但自由度小。
链表从 中分配空间, 自由度大但申请管理比较麻烦. 
逻辑结构区别
数组必须事先定义 固定的长度 (元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。 
链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项) 
数组与链表总结
1、存取方式上,数组可以顺序存取或者随机存取,而链表只能顺序存取; 
2、存储位置上,数组逻辑上相邻的元素在物理存储位置上也相邻,而链表不一定; 
3、存储空间上,链表由于带有指针域,存储密度不如数组大; 
4、按序号查找时,数组可以随机访问,时间复杂度为O(1),而链表不支持随机访问,平均需要O(n); 
5、按值查找时,若数组无序,数组和链表时间复杂度均为O(1),但是当数组有序时,可以采用折半查找将时间复杂度降为O(logn); 
6、插入和删除时,数组平均需要移动n/2个元素,而链表只需修改指针即可; 
7、空间分配方面: 
  数组在静态存储分配情形下,存储元素数量受限制,动态存储分配情形下,虽然存储空间可以扩充,但需要移动大量元素,导致操作效率降低,而且如果内存中没有更大块连续存储空间将导致分配失败; 
  链表存储的节点空间只在需要的时候申请分配,只要内存中有空间就可以分配,操作比较灵活高效

猜你喜欢

转载自blog.csdn.net/v_axis/article/details/77977253