二叉树的存储结构
Created|Updated
|Post Views:
前言
二叉树也有顺序存储结构和链式存储结构。由于二叉树是一种特殊的树,所以也可以通过顺序存储结构来实现。因为是顺序存储结构,所以要用数组来实现。
顺序存储结构
存放数据的区域(数组),而且数组的下标也要体现节点间的逻辑关系。
数组的大小要定义为完全二叉树的大小。当中某些节点有可能是为空的,所以顺序存储结构一般只用于完全二叉树,否则会造成空间的浪费。

链式存储结构
既然顺序存储结构的适用性不强,所以将引入二叉链表。它一般被分为两个区域——数据区和指向左右孩子的指针区。然而它还可以在指针区增加一个指针来指向父母。

1 | typedef struct Node *PtrToNode; |
Related Articles
2020-05-23
二叉查找树
前言二叉查找树的插入,删除等操作上都运用了递归来实现。首先,需要了解递归在执行递归调用之后的语句要以之前保存的变量反方向执行。 Insert这里的if-else看成一块,而return看成另一块。 每次插入会比较节点的大小,大的return右孩子,小的return左孩子,直到找的到孩子为NULL就创建节点T->Left = Insert(X, T->Left);T->Right = Insert(X, T->Right); 如果,我们传入根节点,那么递归调用之前的语句被执行后,均按被调函数相反的顺序执行。所以,最后会传回根节点。 123456789101112131415161718192021SearchTree Insert(ElementType X, SearchTree T){ if(T == NULL) { /* Create and return a one-node tree */ T = malloc(sizeof(TreeNode)); if(T == N...
2022-01-28
Stack
栈栈也是一种线性表,它也可以由顺序表,和链表来实现。 只不过栈是一种被限制的线性表,它只能对栈顶(线性表的最末端的元素)进行基本操作(增删改查)。 本次,主要讲栈的顺序存储结构。 顺序栈结构 数组data[MaxSize] 当前栈顶top 1234typedef struct { ElemType data[MaxSize]; int top;}SqStack; 操作流程图 实现代码1234567891011121314151617181920212223242526272829303132333435363738394041void Init(SqStack &s) { s.top = -1;}bool IsEmpty(SqStack s) { if (s.top == -1) { return true; } return false;}bool IsFull(SqStack s) { if (s.top >= MaxSize - 1) { return...
2022-01-28
Queue
队列队列这种逻辑结构,也能用顺序表和链表实现,本次主要讲用顺序结构实现的循环队列。 队列是一种被限制的线性表,只能在队列的队头进行删除,在队尾进行增加 循环队列首先,我们要先认识一下循环队列。这里的循环队列,我们用顺序结构(数组)实现。 从逻辑上,把队头和队尾拼接起来。(当指针指向队尾,再往前移动一个位置,就%MaxSize) 结构12345typedef struct { ElemType data[MaxSize]; int front;//指向队头元素 int rear;//指向队尾元素的下一个元素} SqQueue; 要面临的两个问题是: 队列为空的条件。 队列为满的条件。 由于队列在增加和删除的过程中,元素在队列中的序号是变化的,所以不能像栈一样用常量-1表示。所以,我们定义q.front == q.rear即队列为空。定义(q.rear + 1) % MaxSize == q.front队列为满。 流程图 基本操作循环队列不像顺序表和链表那样把元素真正增加,删除,而是去更改头尾指针。 出入队时,都让指针往顺时针方向进1 12345678...
2020-05-28
图的遍历
Depth_First_Search过程 从某个顶点v1出发,然后找到并访问与v1的邻接点(且从未访问过)v2,再从v2出发访问与v2相邻的顶点。–>这就是递归思想 直到所有的顶点被访问到。 因为要记录该点是否被访问过,所以需要一个数组bool visited[MAXVEX]; 邻接矩阵遍历12345678910111213141516171819202122void DFS(MGraph G, int i){ int j; visited[i] = true; printf("%c ", G.vexs[i]); for(j = 0; j < G.numVertexs; j++) { //有边(i--j),且 j 顶点没被访问 if(G.arc[i][j] == 1 && visited[j] == false) DFS(G, j); }}void DFSTraverse(MGraph G)...
2022-02-28
Graph
图的存储邻接矩阵我们使用邻接矩阵来表示图的边。 邻接表法这里的表是指链表。 表面一个顶点所邻接的边。
2020-04-17
链表和数组
前言链表就是指动态分配结构的序列链 说明我们知道,数组是被分配的连续的内存块,可以轻易调用其中的项,但是要增加和删除其中的项却很困难。而链表呢,因为它是靠结构中的指针将散乱的内存块,串起来。就变得增加,删除其中的项很容易,要访问其中的某一项却很困难。 构造链表的一般步骤(prev是一个结构指针,表示前一个结构的中介)(current是一个结构指针,表示当前结构的中介) while循环(人为结束) malloc分配结构空间,并返回指针给current(结构将在循环中创建) if-else 给prev的next赋值 将本结构的next = NULL 对本结构的内容赋值 让prev = current的指针 关于结构指针 struct Node *ps定义一个Node类型的结构指针。注意,此时并没有指向Node的某个结构 必须malloc分配结构空间,并返回结构地址,给ps 这样ps才能有类似的ps->next操作 查找随机访问使用数组的时候,用下标访问数组中的元素。就是随机访问。 顺序访问从链表的首节点开始,逐个节点移动到要访问的节点。就是顺序访...
