当前位置: 首页 > news >正文

.net做的大型网站吗做互联网推广的公司

.net做的大型网站吗,做互联网推广的公司,做苗木网站哪家好,2003系统做网站前言 这个专栏将会用纯C实现常用的数据结构和简单的算法;有C基础即可跟着学习,代码均可运行;准备考研的也可跟着写,个人感觉,如果时间充裕,手写一遍比看书、刷题管用很多,这也是本人采用纯C语言…

前言

  • 这个专栏将会用纯C实现常用的数据结构和简单的算法;
  • 有C基础即可跟着学习,代码均可运行;
  • 准备考研的也可跟着写,个人感觉,如果时间充裕,手写一遍比看书、刷题管用很多,这也是本人采用纯C语言实现的原因之一;
  • 欢迎收藏 + 关注,本人将会持续更新。

文章目录

  • 树相关概念
    • 什么是二叉树
      • 二叉树定义
      • 基本概念
      • 基本形态
      • 二叉树性质
        • 性质1
        • 性质2
        • 性质3
        • 性质4
        • 性质五
    • 特殊二叉树
      • 满二叉树
      • 完全二叉树
  • 二叉树创建与遍历
    • 树创建
    • 树遍历
      • 前序
        • 递归
        • 非递归
      • 中序
        • 递归
        • 非递归
      • 后序
        • 递归
        • 非递归
    • 总代码

树相关概念

什么是二叉树

二叉树定义

二叉树是n (n≥0)个结点的有限集合

  • 每个节点最多有两个子节点,分别称为左子节点和右子节点。
  • 左子节点和右子节点可以为空
  • 二叉树的子树也是二叉树。

基本概念

  • 节点的度:一个节点含有的子树的个数称为该节点的度
  • 叶节点度为0的节点称为叶节点
  • 分支节点度不为0的节点,又称为非终端节点
  • 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点,又称为双亲结点
  • 子节点:一个节点含有的子树的根结点称为该节点的子节点,又称为孩子节点
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点
  • 树的度:一棵树中,最大的节点的度称为树的度
  • 节点的层次从根节点开始定义,根为第1层,根的子节点为第2层,以此类推
  • 树的高度或深度:树中节点的最大层次
  • 堂兄弟节点双亲在同一层的节点互为堂兄弟
  • 节点的祖先:从根到该节点所经分支上的所有节点
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙

基本形态

在这里插入图片描述

二叉树性质

性质1

二叉树第k (k>=1)层上至多有2k–1个结点。

思考题

若二叉树具有第k层的结点,那么第k层结点数的取值范围是多少?[1, 2k-1]

性质2

高度为h (h>=0)的二叉树至多有2h - 1个结点

思考题

高度为h的二叉树的结点数范围?

证明:高度为h的二叉树共有h层,第k层节点数范围为[1, 2k-1] ,故可知,高度为h的二叉树至少具有: ∑ k = 1 h 1 = h \sum _{k=1}^{h} 1=h k=1h1=h个节点;高度为h的二叉树至多具有 ∑ k = 1 h 2 k − 1 = 2 0 + 2 1 + . . . + 2 h − 1 = 2 h − 1 \sum ^{h}_{k=1}2^{k-1}=2^0+2^1+...+2^{h-1}=2^h-1 k=1h2k1=20+21+...+2h1=2h1
∑ k = 1 h 2 k − 1 = 2 0 + 2 1 + . . . + 2 h − 1 = 2 h − 1 \sum ^{h}_{k=1}2^{k-1}=2^0+2^1+...+2^{h-1}=2^h-1 k=1h2k1=20+21+...+2h1=2h1

性质3

设二叉树叶子结点数为n0,度为2的结点数为n2,则有:n0= n2+ 1。

性质4

结点数为n的完全二叉树的高度为: log ⁡ 2 n \log_2{n} log2n + 1或 log ⁡ 2 ( n + 1 ) \log_2{(n+1)} log2(n1)

性质五

给有n个结点的完全二叉树按层次编号,对于编号为i的结点:

  • 可计算i结点的双亲结点的编号
    • 若i = 1,则无双亲
    • 否则双亲编号为 i 2 \frac i 2 2i
  • 可计算i结点的左孩子结点的编号
    • 若2*i > n,则无左孩子
    • 否则其左孩子编号为2*i
  • 可计算i结点的右孩子结点的编号
    • 若2*i+1> n,则无右孩子
    • 否则其右孩子编号为2*i+1

特殊二叉树

满二叉树

  • 深度为h且具有2h-1个结点的二叉树
  • 每一层都容纳了该层所能容纳的最大结点数结点的二叉树
  • 没有度数为1的结点,且叶子结点均分布在最大层的二叉树

在这里插入图片描述

思考题

深度为h的满二叉树

  • 结点总数为? 2h - 1
  • 叶子结点数为? 2h-1
  • 度为1的结点数为?0
  • 度为2的结点数为?2h-1-1

具有n个结点的满二叉树

  • 有多少个叶子?(n + 1) / 2
  • 有多少个度为2的结点?(n - 1) / 2

完全二叉树

  • 除去最大层是一棵满二叉树
  • 除去最大层是一棵满二叉树

在这里插入图片描述

完全二叉树的几个非常有趣的特点:

  • 除去最大层是一棵满二叉树
  • 最大层上的结点向左充满
  • 叶子只可能分布在最大层和次大层上。
  • 度为1的结点至多有1个。
  • 一棵满二叉树一定是一棵完全二叉树,而一棵完全二叉树不一定是一棵满二叉树。
  • 对于具有相同结点数的二叉树而言,完全二叉树的高度一定是其中最小的

思考题

高度为h的完全二叉树的结点范围?[ 2k-1, 2k-1]

具有n个结点的二叉树的高度最小值为多少?高度最大值为多少? [ log ⁡ 2 n \log_2{n} log2n+1, n]

  • 完全二叉树最小: log ⁡ 2 n \log_2{n} log2n+1
  • 一层只有一个结点最大:n

二叉树创建与遍历

树创建

节点封装,二叉树,封装就需要封装两个孩子

typedef struct TreeNode {char data;struct TreeNode* LChild;struct TreeNode* RChild;
}TreeNode;TreeNode* create_node(char data)
{TreeNode* new_node = (TreeNode*)calloc(1, sizeof(TreeNode));assert(new_node);new_node->data = data;return new_node;
}

🚸 创建,这里采用“最傻瓜式”创建,如下代码所示:

// 傻瓜式建立树
void create_tree(TreeNode* parent, TreeNode* lChild, TreeNode* rChild)
{// 父亲不为 NULL 即可assert(parent);parent->LChild = lChild;parent->RChild = rChild;
}// 创建如下:
int main()
{// 一个一个创建节点TreeNode* a = create_node('a');   TreeNode* c = create_node('c');TreeNode* d = create_node('d');TreeNode* s = create_node('s');TreeNode* h = create_node('h');TreeNode* e = create_node('e');TreeNode* b = create_node('b');TreeNode* v = create_node('v');TreeNode* m = create_node('m');// 连接create_tree(a, c, d);   // a为跟节点create_tree(c, s, h);create_tree(d, e, b);create_tree(s, NULL, v);create_tree(h, NULL, NULL);create_tree(e, m, NULL);create_tree(b, NULL, NULL);return 0;
}

树遍历

前序

遍历顺序:左中右,动画如下所示(ppt制作):

在这里插入图片描述

递归
// 递归前序
void preorder_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}printf("%c ", root->data);preorder_recursion(root->LChild);preorder_recursion(root->RChild);
}
非递归

借助栈辅助

// 迭代前序遍历
// 注意一点:节点入栈顺序,与出栈顺序
void preorder_travel(TreeNode* root)
{assert(root);// 准备栈TreeNode* stack[1024] = { 0 };int top = -1;stack[++top] = root;while (top != -1) {TreeNode* temp = stack[top];top--;printf("%c ", temp->data);if (temp->RChild != NULL) stack[++top] = temp->RChild;if (temp->LChild != NULL) stack[++top] = temp->LChild;}
}

中序

遍历顺序:中左右

在这里插入图片描述

递归
// 递归中序
void mid_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}mid_recursion(root->LChild);printf("%c ", root->data);mid_recursion(root->RChild);
}
非递归

要注意:还有一个指针跟着栈走

// 中序,回退靠栈
// 核心:cur与栈配合,维护cur指针
void mid_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* cur = root;while (cur != NULL || top != -1) {if (cur != NULL) {stack[++top] = cur;cur = cur->LChild;}else {TreeNode* t = stack[top];top--;printf("%c ", t->data);cur = t->RChild;}}
}

后序

遍历顺序:左右中

在这里插入图片描述

递归
// 递归后序
void last_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}last_recursion(root->LChild);last_recursion(root->RChild);printf("%c ", root->data);
}
非递归

和前序遍历一样,维护一个栈

// 后序
// 核心:pre指针、cur指针,以及什么时候pre 与 cur指针相遇,以及为什么弹出后cur = NULL,pre = cur;
// 动画:想清楚如果一个节点要打印,则情况是什么,pre一直在模拟左、右、中节点
void last_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* used = NULL;TreeNode* cur = root;while (cur != NULL || top != -1) {while (cur) {stack[++top] = cur;cur = cur->LChild;}cur = stack[top];if (cur->RChild == NULL || cur->RChild == used) {printf("%c ", cur->data);top--;used = cur;cur = NULL;}else {cur = cur->RChild;}}
}

总代码

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>typedef struct TreeNode {char data;struct TreeNode* LChild;struct TreeNode* RChild;
}TreeNode;TreeNode* create_node(char data)
{TreeNode* new_node = (TreeNode*)calloc(1, sizeof(TreeNode));assert(new_node);new_node->data = data;return new_node;
}// 傻瓜式建立树
void create_tree(TreeNode* parent, TreeNode* lChild, TreeNode* rChild)
{// 父亲不为 NULL 即可assert(parent);parent->LChild = lChild;parent->RChild = rChild;
}// 递归前序
void preorder_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}printf("%c ", root->data);preorder_recursion(root->LChild);preorder_recursion(root->RChild);
}// 递归中序
void mid_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}mid_recursion(root->LChild);printf("%c ", root->data);mid_recursion(root->RChild);
}// 递归后序
void last_recursion(TreeNode* root)
{if (root == NULL) {printf("NULL ");return;}last_recursion(root->LChild);last_recursion(root->RChild);printf("%c ", root->data);
}// 迭代前序遍历
// 注意一点:节点入栈顺序,与出栈顺序
void preorder_travel(TreeNode* root)
{assert(root);// 准备栈TreeNode* stack[1024] = { 0 };int top = -1;stack[++top] = root;while (top != -1) {TreeNode* temp = stack[top];top--;printf("%c ", temp->data);if (temp->RChild != NULL) stack[++top] = temp->RChild;if (temp->LChild != NULL) stack[++top] = temp->LChild;}
}// 中序,回退靠栈
// 核心:cur与栈配合,维护cur指针
void mid_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* cur = root;while (cur != NULL || top != -1) {if (cur != NULL) {stack[++top] = cur;cur = cur->LChild;}else {TreeNode* t = stack[top];top--;printf("%c ", t->data);cur = t->RChild;}}
}// 后序
// 核心:pre指针、cur指针,以及什么时候pre 与 cur指针相遇,以及为什么弹出后cur = NULL,pre = cur;
// 动画:想清楚如果一个节点要打印,则情况是什么,pre一直在模拟左、右、中节点
void last_travel(TreeNode* root)
{assert(root);TreeNode* stack[1024] = { 0 };int top = -1;TreeNode* used = NULL;TreeNode* cur = root;while (cur != NULL || top != -1) {while (cur) {stack[++top] = cur;cur = cur->LChild;}cur = stack[top];if (cur->RChild == NULL || cur->RChild == used) {printf("%c ", cur->data);top--;used = cur;cur = NULL;}else {cur = cur->RChild;}}
}int main()
{// 一个一个创建节点TreeNode* a = create_node('a');   TreeNode* c = create_node('c');TreeNode* d = create_node('d');TreeNode* s = create_node('s');TreeNode* h = create_node('h');TreeNode* e = create_node('e');TreeNode* b = create_node('b');TreeNode* v = create_node('v');TreeNode* m = create_node('m');// 连接create_tree(a, c, d);   // a为跟节点create_tree(c, s, h);create_tree(d, e, b);create_tree(s, NULL, v);create_tree(h, NULL, NULL);create_tree(e, m, NULL);create_tree(b, NULL, NULL);printf("递归前序: \n");preorder_recursion(a);    printf("\n递归中序: \n");mid_recursion(a);printf("\n递归后序: \n");last_recursion(a);printf("\n迭代前序: \n");preorder_travel(a);printf("\n迭代中序: \n");mid_travel(a);printf("\n迭代后序: \n");last_travel(a);return 0;
}
http://www.hkea.cn/news/796378/

相关文章:

  • html做的好看的网站如何宣传推广产品
  • 微信手机网站制作怎么引流客源最好的方法
  • 宿州建设网站公司前端seo搜索引擎优化
  • 做王境泽表情的网站百度seo关键词优化排名
  • 怎么选择无锡网站建设虚拟主机搭建网站
  • 做原油期货关注什么网站搜索引擎优化是做什么
  • 微信小程序怎么制作游戏安卓优化清理大师
  • 胶南做网站初学者做电商怎么入手
  • 网站为什么要维护佛山网络营销推广
  • 国企网站建设报告怎么建造自己的网站
  • 免费做司考真题的网站余姚网站如何进行优化
  • 如何网站开发1688网站
  • 丽水专业网站建设价格青岛网站优化
  • 网站开发专业培训学校百度推广登录官网入口
  • 贵阳做网站公司网站热度查询
  • 做课件最好的素材网站考拉seo
  • 网站建设玖首选金手指seo网站优化收藏
  • 台州卓远做网站好不好广州seo教程
  • dz网站数据备份bt磁力猪
  • github 可以做网站吗360seo
  • 杭州 企业门户网站建设爱链
  • dj那个网站做的好长沙公司网络营销推广
  • 设计师培训招生视频黑帽seo联系方式
  • 做网上贸易哪个网站好西宁网站seo
  • 电子烟网站建设杯子软文营销300字
  • 广州企业网站制作怎么做营销推广
  • 网站建设服务器在香港郑州网站建设专业乐云seo
  • 河北建设工程交易信息网海口关键词优化报价
  • 全国网站建设公司有多少家微信朋友圈广告投放收费标准
  • 免费做网站公司黑帽seo排名技术