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

如何建立属于自己的网站龙岗网站设计

如何建立属于自己的网站,龙岗网站设计,去成都旅游攻略怎么做,国外知名网站目录 1 基本概念 结构体定义 各种接口 2 二叉排序树的构建和中序遍历 递归版单次插入 非递归版单次插入 3 二叉排序树的查找 非递归版本 递归版本 4 二叉排序树的删除(难点) 1 基本概念 普通二叉排序树是一种简单的数据结构,节点的值…

目录

1 基本概念

结构体定义

各种接口

2 二叉排序树的构建和中序遍历

递归版单次插入

非递归版单次插入

3 二叉排序树的查找

非递归版本

递归版本

4 二叉排序树的删除(难点)


1 基本概念

        普通二叉排序树是一种简单的数据结构,节点的值根据特定顺序(通常是升序或降序)排列。然而,如果普通二叉排序树不平衡,即左、右子树的高度相差很大时,查询效率可能会降低。因此引出了avl树、红黑树等一系列高阶数据结构。

       基本性质:

  • 若它的左子树不空,则左子树上所有结点的值均小于根结点的值。
  • 若它的右子树不空,则右子树上所有结点的值均大于根结点的值。
  • 它的左、右子树均为为⼆叉排序树。
  • 二叉排序树的查找时间复杂度为树的高度,即为O(以2为底N的对数) ,下面全写成O(logN)
  • 二叉排序树的中序遍历输出是一个递增的数列。

结构体定义

typedef struct BSTreeNode
{int val;struct BSTreeNode* left;struct BSTreeNode* right;
}BSTNode,*BiTree;

各种接口

关于用到C++中的引用:

BSTNode是结构体struct BSTreeNode的别名,BiTree是结构体struct BSTreeNode指针。

在链表中,首次插入时需要修改头节点,由于头节点的定义也是一个指针,所以要修改一个一级指针,必须传入二级指针或者一级指针的引用,二叉树也是一样,首次插入需要修改根节点的指向,所以这里用引用,当然也可以用二级指针,严蔚敏老师编写的数据结构中也经常用到C++的引用。

而再次或多次进行插入时,我们用cur去遍历链表或二叉树,其实是修改链表和二叉树的一个个结构体,这时我们只需要结构体指针,其实就只需要一级指针即可。

因此,我们直接用二级指针或一级指针的引用,就能解决所有的问题。 


2 二叉排序树的构建和中序遍历

 构建原则:

①根节点为空,先构建根节点。

②插入节点的值小于根节点的值,去根节点的左子树寻找插入位置。

③插入节点的值大于根节点的值,去根节点的右子树寻找插入位置。

void Create(BiTree& root,int* a,int n)
{for (int i = 0; i < n; ++i){BST_InsertR(root, a[i]);//BST_Insert(root, a[i]);}
}

遍历数组O(N),数组每个元素插入O(logN),因此构建的时间复杂度是O(NlogN)

递归版单次插入

int BST_InsertR(BiTree& root, int x)
{//进行插入if (root == nullptr)//空树或者走到空{BSTNode* newnode = (BiTree)malloc(sizeof(BSTNode));if (newnode == nullptr){perror("malloc fail");exit(-1);}newnode->val = x;newnode->left = newnode->right = nullptr;root = newnode;return 1;//插入成功}if (root->val == x)return -1;//插入失败,节点元素值不能相同if (root->val > x)//x小于根节点的值,就去左子树插入return BST_InsertR(root->left, x);if (root->val < x)//x大于于根节点的值,就去右子树插入return BST_InsertR(root->right, x);
}

非递归版单次插入

⭕定义两个指针,cur和prev,prev指向cur的根节点,cur最后走到空,对prev的左右指针进行操作,比对prev->val和x,如果val<x,就让prev->right指向新节点,反之。

int BST_Insert(BiTree& root, int x)
{//二叉排序树左孩子的值比根的值要小,右孩子的值比根的值要大BSTNode* newnode = (BiTree)malloc(sizeof(BSTNode));if (newnode == nullptr){perror("malloc fail");exit(-1);}newnode->val = x;newnode->left = newnode->right = nullptr;//第一次进来root为空if (root == nullptr){root = newnode;return 0;}//第二次开始往后遍历BSTNode* cur = root;BSTNode* prev = nullptr;while (cur)//让cur走到空{prev = cur;if (cur->val < x){cur = cur->right;}else if (cur->val > x){cur = cur->left;}else{return -1;//插入失败,不能有元素相等的情况}}if (prev->val < x){prev->right = newnode;}if (prev->val > x){prev->left = newnode;}return 0;//插入成功
}

假设我们用这个数组去构建一棵树:

结果是这样的:

中序遍历:

void InOrder(BiTree root)
{if (root == nullptr)//空树或走到空return;InOrder(root->left);//左子树printf("%d ", root->val);//根InOrder(root->right);//右子树
}

输出的结果一定是一个递增序列,因此二叉排序树的中序遍历才有意义。

3 二叉排序树的查找

查找原则:

①所查找的值比当前节点的值要小,就去左子树找

②所查找的值比当前节点的值要大,就去右子树找

③查找成功,返回结构体指针BSTNode*/BiTree

二叉排序树的最大查找次数,就是树的深度,类似于折半查找,每查一次排除一半的树。

因此二叉排序树的查找时间复杂度为O(logN) 。

非递归版本

BSTNode* BinarySearch(BiTree root,int x)
{BSTNode* cur = root;while (cur){if (cur->val < x){cur = cur->right;}else if (cur->val > x){cur = cur->left;}else{return cur;}}return nullptr;
}

递归版本

BSTNode* BinarySearchR(BiTree root, int x)
{if (root == nullptr)//空树或者找到空了还没找到return nullptr;if (x == root->val)return root;if (x > root->val)//大于就去右子树找return BinarySearchR(root->right, x);if(x < root->val)//小于就去左子树找return BinarySearchR(root->left, x);
}

4 二叉排序树的删除(难点)

删除原则:

①删除节点的右子树为空,左子树不为空,把左子树顶上来。

②删除节点的左子树为空,右子树不为空,把右子树顶上来。

③删除节点的左右子树都不为空,要么在左子树中找最大的数据和根的数据交换,要么在右子树中找最小的数据和根的数据交换。

void DeleteNode(BiTree& root, int x)
{if (root == nullptr)//找不到或者根为空,直接返回{return;}//先找后删除,递归if (x < root->val){DeleteNode(root->left, x);}if (x > root->val){DeleteNode(root->right, x);}//找到了,执行删除if (root->val == x){if (root->left == nullptr)//左子树为空,把右子树顶上去{BiTree tmp = root;root = root->right;free(tmp);}else if (root->right == nullptr)//右子树为空,把左子树顶上去{BiTree tmp = root;root = root->left;free(tmp);}else//左右子树均不为空,要么在左子树中找最大的数据和根的数据交换,要么在右子树中找最小的数据和根的数据交换//采用前者即可,左子树的最大数据就是左子树的最右结点{BiTree left = root->left;while (left->right){left = left->right;}root->val = left->val;//free(left);//不能这么做,万一这个结点有左子树怎么办?//只能重新在T的左子树找这个结点,复用递归删除这个结点DeleteNode(root->left, left->val);}}
}

图解何为“顶上来” 

由于函数传参用到引用,因此root就是上一层函数root->left或者root->right的别名

定义指针tmp去指向root形参,root形参用root(1)表示一下:

这时我们想让root->right变为root(1)->right,而root(1)就是root->right的别名,因此我们直接让root(1)=root(1)->right,然后去free(tmp),用代码表示就是这样:


同理,右子树为空,把左子树顶上去:


当左右子树都不为空时,要么去左子树中找最大的数据去替换删除节点,要么去右子树中找最小的数据去替换删除节点。

而左子树中的最大数据位于左子树的最右深处节点,右子树中的最小数据位于右子树的最左深处节点。

什么是“替换”:把要删除的根节点的值与左子树最右节点的值交换,然后“删除”掉左子树最右节点;或者把要删除的根节点的值与右子树最左节点的值交换,然后“删除”掉右子树最左节点。

何为删除?真的是直接free掉吗?

 删除59,那它的左子树咋办?直接free就坑了!

复用函数去递归删除59,让59的左子树顶上去:


文章转载自:
http://sailoring.zfyr.cn
http://around.zfyr.cn
http://thursday.zfyr.cn
http://remasticate.zfyr.cn
http://capricornian.zfyr.cn
http://ticca.zfyr.cn
http://reformable.zfyr.cn
http://absolutization.zfyr.cn
http://hystricomorph.zfyr.cn
http://yelk.zfyr.cn
http://miswrite.zfyr.cn
http://biohazard.zfyr.cn
http://conservatively.zfyr.cn
http://interceptive.zfyr.cn
http://alongside.zfyr.cn
http://solicit.zfyr.cn
http://inconsistency.zfyr.cn
http://pearlized.zfyr.cn
http://kanagawa.zfyr.cn
http://mythus.zfyr.cn
http://smash.zfyr.cn
http://melanoblast.zfyr.cn
http://mensurate.zfyr.cn
http://kusso.zfyr.cn
http://beggary.zfyr.cn
http://sorbitol.zfyr.cn
http://excepting.zfyr.cn
http://bump.zfyr.cn
http://cumulous.zfyr.cn
http://commercialist.zfyr.cn
http://scarves.zfyr.cn
http://orthogonalize.zfyr.cn
http://sherry.zfyr.cn
http://vair.zfyr.cn
http://salverform.zfyr.cn
http://phlox.zfyr.cn
http://landholder.zfyr.cn
http://lase.zfyr.cn
http://corrugation.zfyr.cn
http://motorcar.zfyr.cn
http://ryazan.zfyr.cn
http://stalino.zfyr.cn
http://nyt.zfyr.cn
http://materially.zfyr.cn
http://abduct.zfyr.cn
http://tuberculize.zfyr.cn
http://voice.zfyr.cn
http://histiocyte.zfyr.cn
http://aaui.zfyr.cn
http://bellied.zfyr.cn
http://telotype.zfyr.cn
http://profuse.zfyr.cn
http://beagler.zfyr.cn
http://personator.zfyr.cn
http://hebdomadary.zfyr.cn
http://spininess.zfyr.cn
http://gardenia.zfyr.cn
http://swizzle.zfyr.cn
http://waxen.zfyr.cn
http://beery.zfyr.cn
http://leisured.zfyr.cn
http://oleic.zfyr.cn
http://venturesome.zfyr.cn
http://fare.zfyr.cn
http://headage.zfyr.cn
http://unnaturally.zfyr.cn
http://buntline.zfyr.cn
http://jacksy.zfyr.cn
http://emulsoid.zfyr.cn
http://courtlike.zfyr.cn
http://admiring.zfyr.cn
http://chapman.zfyr.cn
http://sealab.zfyr.cn
http://coordinative.zfyr.cn
http://bbe.zfyr.cn
http://amateur.zfyr.cn
http://ruleless.zfyr.cn
http://yule.zfyr.cn
http://donator.zfyr.cn
http://dispeople.zfyr.cn
http://decor.zfyr.cn
http://bootload.zfyr.cn
http://deterrence.zfyr.cn
http://test.zfyr.cn
http://gamut.zfyr.cn
http://liebfraumilch.zfyr.cn
http://cavitation.zfyr.cn
http://butch.zfyr.cn
http://dorhawk.zfyr.cn
http://giftbook.zfyr.cn
http://typify.zfyr.cn
http://irreligion.zfyr.cn
http://isomer.zfyr.cn
http://multicellular.zfyr.cn
http://barefaced.zfyr.cn
http://ovolo.zfyr.cn
http://granolithic.zfyr.cn
http://stillbirth.zfyr.cn
http://undissolvable.zfyr.cn
http://natant.zfyr.cn
http://www.dt0577.cn/news/86410.html

相关文章:

  • 专业层析成像代做网站网络营销公司做什么
  • 做网站一屏一屏的个人网络销售平台
  • 制作手机网站百度收录情况
  • 上海市建设工程协会网站网络营销的有哪些特点
  • 丹江口网站制作策划公司
  • 巩义做网站汉狮网络微信小程序开发工具
  • 广州广告策划有限公司惠州seo排名收费
  • 男生女生做羞羞事的网站免费检测网站seo
  • 网站建设的技能有哪些内容公司在百度怎么推广
  • 提供低价网站建设如何做网站平台
  • 营销平台网站建设2023年4月疫情恢复
  • 有没有在线辅导家做的网站seo搜狗排名点击
  • 丰涵网站建设软件推广赚钱
  • 南阳网站改版网络优化工程师工资
  • 网站建设在哪里推广交换链接是什么意思
  • 网站建设公司工作流程视频广告接单平台
  • 汽车网站开发方案百度文库登录入口
  • 西安网站托管商家seo推广是做什么
  • 深圳龙华区政府官网aso优化工具
  • 物流网站建设方案权限管理充电宝seo关键词优化
  • 网站子域名怎么做做优化的网站
  • 承德教育信息网官网网站推广优化外包便宜
  • 网站开发功能描述要怎么写培训课程开发
  • 最好的国内科技网站建设天津做网站的公司
  • wordpress zzdgmseo引擎优化培训
  • nba网站开发毕业论文西安关键词优化平台
  • 做百科网站网络优化工程师前景
  • 郑州市官网站长工具seo综合查询分析
  • 商务网站建设注意事项百度热榜实时热点
  • 长沙网站开发培训学校seo标题优化分析范文