一、数据结构的认识
数据结构:数据,逻辑结构,存储结构,操作
1.1数据
数据是信息的载体,是能够输入到计算机系统被计算机识别,处理,存储的符号总称
数据元素是数据的基本单位,又称为一条记录,数据元素包含有基本的数据项;
例如,图书管理系统,a1是数据元素,包含的数据项有:编号,书名,作者,出版社,出 版日期。。。
数据类型:在数据元素的数据项,每一个数据项都会有数据类型;
1.2数据的逻辑结构
线性结构:1对1的逻辑关系,顺序表,栈,队列
树形结构:1对多的逻辑关系,1对2的二叉树关系
图状结构:多对多的逻辑关系,例如,竞赛拍时间等
逻辑结构:数据自带的,取决于你研究的对象;数据的属性决定;逻辑结构,程序员是要 发现它,用已经知道的几种结构类型去找寻规律;
1.3数据的存储结构
存储结构:是要遵从的数据原本的逻辑结构进行映射存放到计算机的存储单元;逻辑结构 不能改变;
数据存储结构的分类:
顺序存储结构:内存的连续空间,顺序且连续
链式存储结构:数据元素之间的关系通过指针建立,在内存可以是不连续的空间
索引存储结构:数据元素的某个数据项和地址之间建立一张索引表。增加查找的效率 哈希存储结构:建的数据元素的某一个数据项(key)和地址之间的映射关系。
顺序存储-----线性表,顺序表
链式存储-----链表
索引存储----索引表
散列存储-----hash表。哈希表
存储结构是要保留逻辑结构,不能改变数据本身的逻辑,之余具体的存储方法,程序员依 据实际业务需求,是可以决定的;
1.4操作
数值类型的操作:加减乘除;
非数值类的操作:
1.创建
2.插入
3.查找
4.删除
5.销毁
6.排序,遍历
二、顺序表
逻辑结构:1对1的线性结构,元素除了首和尾,中间的元素,有且只有一个前驱和一个后 继;
- 存储结构:按顺序进行存储,内存中连续且大小固定;
顺序表的特点:
顺序并且连续存储
大小固定,提前申请好内存的空间
表满不能存,表空不能删除数据
操作:增删改查;插入和删除元素不太方便。需要移动元素
访问和查找比较方便
2.1定义顺序表
2.2创建一个顺序表
2.3增加一个元素
2.4删除一个元素
2.5顺序表的显示
2.6顺序表的销毁
三、链表
顺序存储的缺点:
3.1单链表
3.1.1单链表的定义
3.1.2结点的定义(以单向不循环链表为例)
3.1.3链表的操作
3.1.3.1链表的插入
头部插入:
中间插入:
尾部插入:
3.1.3.2链表的删除
头部删除:
中间删除:
尾部删除:
3.1.3.3显示
3.1.3.4销毁
3.1.3.5逆序
3.2双链表
3.2.1定义双链表
3.2.2双链表的插入
3.2.3双链表的删除
3.2.4双链表的显示
四、栈
- 限制在一端进行操作:
- 先进后出
4.1顺序栈
4.1.1顺序栈的定义
4.1.2创建顺序栈
![](https://i-blog.csdnimg.cn/blog_migrate/31fb0d6f76afff755c9b97ef592c6172.png)
4.1.3入栈
4.1.4出栈
4.1.5显示
4.2链式栈
五、队列
队列的特点:
1.先进先出
- 2.只允许在队尾插入,对头删除
六、树
6.1树的概念
树是具有n(n >= 0)个结点的有限集合
满足树的两个条件:
1.有且仅有一个根结点;
2.其余的结点可以分为m(m>=0)个互不相交的有限集合;
注意:根节点没有前趋节点,叶节点没有后继节点
度数:
一个节点子树的个数称为该节点的度数,一棵树的度数指的是该树种节点的最大度数
树叶:
度数为0的节点称为树叶(终端节点)
边数:
一个节点系列k1,k2, ……,ki,ki+1, ……,kj,并满足ki是ki+1的父节点,就称为一条从k1到kj的路径,路径的长度为j-1,即路径中的边数
深度:
节点的层数等于父节点的层数加1,根节点的层数定义为1,树种节点的最大值称为该树的高度或深度
6.2二叉树
6.2.1概念
二叉树(Binary Tree)是n(n≥0)个节点的有限集合,它或者是空集(n=0),或者是由一个根节点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成。
注意:二叉树严格区分左孩子和右孩子,即使只有一个子节点也要区分左右
特征:
1、二叉树最多有两个子节点
2、严格区分左子树和右子树
6.2.2性质
- 二叉树第i(i≥1)层上的节点最多为2^i-1个。
- 深度为k(k≥1)的二叉树最多有2^k -1个节点
总结点的个数: n = 2^0 + 2^1 + 2^2 +.......+2^(k-1)
2n = 2^1 + 2^2 + ........2^(k-1)+2^k
两个相减得:n = 2^k-1
案例1、具有1000个节点的二叉树的最小深度为_____(第一层深度为1)
A.11 B.12 C.9 D.10
3.在任意一棵二叉树中,树叶的数目比度数为2的节点的数目多一。
方法1:
所有的节点n
度数为0的节点所有的个数为n0,它的子节点为0
度数为1的节点所有的个数为n1,它的子节点为n1
度数为2的节点所有的个数为n2, 它的子节点为2n2
n = n0 + n1 + n2
方法2:
所有节点的个数n = 所有的子节点的个数 + 1(根节点)
n = 0 + n1 +2n2 + 1
n0 + n1 + n2 = 0 + n1 + 2n2 + 1
n0 = n2 + 1
2、具有10个叶节点的二叉树有( )个度数为2的节点
A.8 B.9 C.10 D.11
6.2.3满二叉树
6.2.4完全二叉树
对一棵满二叉树,从下往上,从右往左,依次去掉若干个节点形成的树,就称为完全二叉树
6.2.5顺序存储
1、将不完全二叉树变成完全二叉树
2、将完全二叉树从上到下,从左到右进行编号,根节点的编号为1
3、有n个节点的完全二叉树可以用有n+1个元素的数组进行顺序存储,节点号和数组下标一一对应,下标为零的元素不用
6.2.6链式存储
1、定义数据元素的类型
typedef char data_type;
2、定义二叉树节点的数据类型
typedef struct treeNode
{
struct treeNode *lChild;
data_type data;
struct treeNode *rChild;
}Tree;
6.2.7二叉树的遍历
(1)非递归遍历
(2)递归遍历
1、前序遍历
先访问根节点,再访问左子树,最后访问右子树(根左右)
void preOrder(Tree *pBoot)
{
if(NULL == pBoot)
{
return ;
}
printf(“%d”,pBoot->data);//先访问根节点
preOrder(pBoot->lChild);//再访问左子树
preOrder(pBoot->rChild);//最后访问右子树
}
2、中序遍历
先访问左子树,然后再访问根节点,最后访问右子树(左根右)
void midOrder(Tree *pBoot)
{
if(NULL == pBoot) return ;
midOrder(pBoot->lChild);
printf(“%d”,pBoot->data);
midOrder(pBoot->rChild);
}
3.后序遍历
先访问左子树,再访问右子树,最后访问根节点(左右根)
void postOrder(Tree *pBoot)
{
if(NULL == pBoot) return;
postOrder(pBoot->lChild);
postOrder(pBoot->rChild);
printf(“%d”,pBoot->data);
}
6.2.8赫夫曼树
赫夫曼(Huffman)树,又称最优树,是带权路径长度最短的树,有着广泛的应用
树的带权路径长度是指所有叶子节点的带权路径长度之和,记作 WPL 。WPL最小的二叉树就是最优二叉树,又称为赫夫曼树
注意:赫夫曼树不唯一,为了保证赫夫曼树的唯一性,遵循左小右大(权值)的原则
6.2.9创建一颗有序树
54 26 33 99 78 18 6 49 22 11
将第一个树作为树根
后面的树如果比树根大作为右子树,比树根小作为左子树