数据结构 # 二叉树/堆/栈
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
逻辑结构包括:
1.集合
数据结构中的元素之间除了“同属一个集合” 的相互关系外,别无其他关系;
2.线性结构
数据结构中的元素存在一对一的相互关系;
3.树形结构
数据结构中的元素存在一对多的相互关系;
4.图形结构
数据结构中的元素存在多对多的相互关系。
================
效果:1、对于,数据结构、堆栈的简单总结。2、链表的操作!
> 数据结构
-
> 自引用结构
struct list { int data; struct list *next; } a;
-
> 线性链表
list.h: #include <stdio.h> #include <stdlib.h> typedef char DATA; /* will use char in examples. */ struct linked_list { DATA d; struct linked_list *next; }; typedef struct linked_list ELEMENT; typedef ELEMENT *LINK;
- > 链表操作
#include "list.h" #include <stdlib.h> LINK string_to_list(char s[]) { LINK head; if (s[0] == '\0') /* base case. */ return NULL; else { head = malloc(sizeof(ELEMENT)); head -> d = s[0]; head -> next = string_to_list(s+1); return head; } }
-
* 插入(insert)
/* Inserting an element in a linked list. */ void insert(LINK p1, LINK p2, LINK q) { assert(p1 -> next == p2); p1 -> next = q; /* insert */ q -> next = p2; }
-
* 删除(delete)
/* Recursive deletion of a list. */ void delete_list(LINK head) { if (head != NULL) { delete_list(head -> next); free(head); /* release storage */ } }
> 堆栈
-
堆栈(压入、弹出)
-
堆栈、是暂时存放数据和地址,通常用来保护断点和现场;
-
堆,队列优先,先进先出(First-In/First-Out);
-
栈,先进后出(First-In/Last-Out)。
-
-
ADT Stack(堆栈)
-
1、只能在一端(称为栈顶(top))对数据项进行插入和删除
-
2、push(压入==增)、pop(弹出==删)、top(取顶部元素==查)、empty(判断是否为空)、full(判断是否已满)和reset(重置==init)
================
|--> Copyright (c) 2015 Bing Ma.
|--> GitHub RUL: https://github.com/SpongeBob-GitHub
================
> 二叉树
-
二叉树
-
树(tree)是一种称为节点(node)的元素的有限集合。
-
树具有一个唯一节点(根节点),每个节点最多具有2个子节点(左孩子、右孩子)。
-
叶节点、它的左右孩子节点为NULL
-
遍历(Traversal)
-
是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问!
-
树的遍历:1、沿链表移动;2、根据下标访问,指向链表的数组元素。
-
[ 通过根节点访问时间决定 ]
-
中序(inorder):先访问左子树,再访问根节点
-
左->根->右(必须递归遍历完后,再进行下一步)
-
前序(preorder):先访问根节点
-
根->左->右
-
后序(postorder):访问完左右子树后,才访问根节点
-
左->右->根
-
Binary Tree
/* Inorder binary tree traversal. */ void inorder (BTREE root) { if (root != NULL) { inorder(root -> left); /* recur left */ printf("%c", root -> d); inorder(root -> right); /* recur right */ } }
-
/* Output: A B C D E F G H I J */
-
前序和后序函数:
- // [ preorder ]
/* Preorder and postorder binary tree traversal. */ void preorder (BTREE root) { if (root != NULL) { printf("%c", root -> d); preorder(root -> left); /* recur left */ preorder(root -> right); /* recur right */ } }
- /* Output: G D B A C F E I H J */
-
// [ postorder ]
void postorder (BTREE root) { if (root != NULL) { postorder(root -> left); /* recur left */ postorder(root -> right); /* recur right */ printf("%c", root -> d); } }
-
/* Output: A C B E F D H J I G */
-
创建BTREE
/* Creating a binary tree. */ BTREE new_node(void) { return (malloc(sizeof(NODE))); } BTREE init_node (DATA d1, BTREE p1, BTREE p2) { BTREE t; t = new_node(); t -> d = d1; t -> left = p1; t -> right = p2; return t; }
PS:一般栈区中的内存,系统会自己管理;作为Coder,我们只需管理堆区的内存分配&释放!
================
# 总结 #
-
1 抽象数据类型(ADT)堆栈可以使用链表来实现,对它的限制在它的第一个元素(称为顶部)。堆栈具有后进先出(LIFO)的特性,这个行为是由push()和pop()函数实现。
-
2 ADT队列也可以用链表来实现,对它的访问限制在它的头部和尾部。队列具有先进先出(FIFO)的特性,这个行为是由enqueue()和dequeue()函数实现的。
-
3 当算法使用迭代方式实现时,需要使用一个迭代循环,在监测到NULL时终止。迭代算法的代价是需要使用辅助指针,但它的效率一般高于递归算法。
-
4 链表处理的标准算法用递归来实现非常自然。基本条件常常就是检测到NULL链。一般条件通过在链表结构中移动链来进行递归。
-
5 二叉树由包含两个链成员的结构来表示,它组合了线性链表的动态特征,并且可以非常快地访问树中的每个元素。二叉树的元素之间的距离通常是对数级的。
-
6 二叉树最常用使用三种遍历方法。每种访问方法是通过根节点的访问时间决定的。这三种遍历方式都可以用递归来实现,从左向右链接每棵子树。
-
7 PS:自引用结构使用指针来访问相同类型结构的地址!!最简单的自引用结构是线性链表。每个元素指向它的下一个元素,最后一个元素指向NULL。
-
8 malloc()函数用于动态内存分配。free()函数用于释放参数所指向的内存,把它返回给系统,供以后使用。
-
9 我们可以指定同时涉及链表和数组的具有可怕复杂性的数据结构。其中一个例子就是实现普通树。在普通树中,每个节点可以具有任意数量的孩子。节点的孩子由链表来表示,它由一个头元素数组所指向。
================
PS:
[ 每日一句 ]
“Nowadays, I don't really know where I'm going, but I hope I go far. ”
[ 每天一首英文歌 ]
" This Love " - Taylor Swift
================
|-> GitHub: SpongeBob-GitHub
|--> Copyright (c) 2015 Bing Ma.
" There's always more to learn, and there are always better ways to do what you've done before. " -- Trybst