数据结构-DAY06
一、树的概念
1.链表是数的一部分(斜树)
2.树的查找速度很快
3.层序:前序:根左右 中序:左根右 后序: 左右根
4.树的存储:顺序结构,链式结构
5.特点:
1,每个结点最多两个子树。
2,左子树和右子树是有顺序的,次序不能颠倒。
3,如果某个结点只有一个子树,也要区分左,右子树。
6.特殊的二叉树
1,斜树,所有的结点都只有左子树,左斜树,所有结点都只有右子树,右树。
2,满二叉树,所有的分支结点都存在左右子树,并且叶子都在同一层上。
3,完全二叉树,对于一颗有n个结点的二叉树按层序编号,如果编号i(1<=i<=n)的结点于同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这可树为完全二叉树。
7.特性
1,在二叉树的第i层上最多有2^(i-1)个结点 i>=1
2,深度为k的二叉树至多有2^k -1 个结点 k>=1
3,任意一个二叉树T,如果其叶子结点的个数是n0,度数为2的结点数为n2, n0 = n2 +1;
4,有n个结点的完全二叉树深度为(logn/log 2) +1;
二、哈希表的概念
1.哈希表:哈希表的作用是用来查找和存储
2.哈希表(Hash Table)是一种基于哈希函数实现的数据结构,用于高效地存储和检索键值对。它通过将键映射到数组中的特定位置来实现快速访问,平均时间复杂度为 O(1)。
3.基本原理:哈希表的核心是哈希函数,它将任意大小的数据映射到固定大小的值(通常是一个整数),这个值称为哈希值。哈希值用于确定键值对在数组中的存储位置。
4.冲突的处理:由于哈希函数可能将不同的键映射到相同的哈希值,因此会发生哈希冲突。常见的冲突解决方法包括链地址法和开放地址法。
5.链地址法:每个数组位置存储一个链表,所有哈希值相同的键值对都存储在这个链表中。
开放地址法:当发生冲突时,通过探测方法(如线性探测、二次探测)寻找下一个可用的位置。
哈希表的优缺点
6.优点:平均时间复杂度为 O(1),适合处理大量数据。
缺点:哈希冲突可能导致性能下降,哈希函数的设计对性能影响较大。
三、例题与练习
1.内核中链表是双向循环链表
Linux第一宏,内核链表可以把程序的耦合性降到最低
offset:传入结构体,成员,通过宏进入,计算node的偏移量是多少
contrainof:返回该类型指针的地址
2.创建树
void CreateTree(TreeNode **root)
{char c = data[ind++];if('#' == c){*root = NULL;return ;}else{*root = malloc(sizeof(TreeNode));if(NULL == *root){fprintf(stderr,"CreateTree malloc error");return ;}(*root)->data = c;CreateTree(&(*root)->left);CreateTree(&(*root)->right);}
}
3.前序遍历
void PreOrderTraverse(TreeNode *root)
{if(NULL == root){return ;}printf("%c",root->data); // rootPreOrderTraverse(root->left); // leftPreOrderTraverse(root->right); // right
}
4.摧毁树
void DestroyTree(TreeNode *root)
{if(NULL == root){ return; }DestroyTree(root -> left);DestroyTree(root -> right);free(root);
}
5.定义结构体
typedef char DATATYPE; // 将char类型重命名为DATATYPE,方便后续使用,可灵活替换树节点数据类型typedef struct _tree_node_
{DATATYPE data; // 树节点存储的数据,类型为前面定义的DATATYPE(即char)struct _tree_node_ *left, *right; // 指向左子节点和右子节点的指针
} TreeNode;全局变量定义
char data[] = "abd#f###c#eg###"; // 用于构建树的字符数组,按特定格式表示树的节点,'#'表示空节点
int ind = 0; // 用于记录在data数组中当前处理的位置索引