数据结构——左高树(C语言)
来源:互联网 发布:纺织erp软件 编辑:程序博客网 时间:2024/06/06 21:26
介绍左高树之前,先简单介绍下扩充二叉树的概念。扩充二叉树一棵二叉树,其所有空的子树都由方形结点代替。方形结点称为外部结点,原来的结点称为内部结点。
设x是扩充二叉树的一个结点,并令left_child(x)和right_child(x)分别表示内部结点的左、右儿子。定义shortest(x)为从x到一个外部结点的最短路程长度。
左高树
定义
左高树是一棵二叉树,且如果该二叉树不空,则对其中的每个内部结点x,都有:
Shortest(left_child(x))>= Shortest(right_child(x))。
左高树的一个应用是合并操作,应用场景是:当某个优先队列的服务器关闭时,就需要将其与另一个正在运行服务器的优先队列合并.如果两个队列的元素总数为n,则一般的堆结构的复杂度为n,但是左高树可以达到log(n).插入和删除操作都可以通过合并操作来完成。
最小(最大)左高树是一棵左高树,其中的每个内部结点的关键字值不大于(不小于)该结点的儿子结点的关键字值。
以下讨论最小左高树的操作:
插入和删除最小元素操作都可以通过合并操作来完成。要把元素x插入到左高树A中,先建立一棵只有一个元素x的最小左高树B,再合并最小左高树A和B。要从一棵非空最小左高树A删除最小元素,则只需合并最小左高树A的左子树和右子树,再把最小左高树的根结点删除。
以下重点介绍最小左高树的合并操作。
假设要合并最小左高树A和B,首先,沿着A和B的最右路径,得到一棵包含A和B所有元素的二叉树(注意:这里只是得到二叉树,而不是最小左高树)。使得该二叉树具有以下性质:所有结点的关键字都不大于其儿子结点关键字。必要时交换结点的左、右子树,将其转化为最小左高树。
合并操作
步骤:
1、 假设合并最小左高树A和B,首先比较两棵树根结点的关键字值,以最小的关键字作为新二叉树的根结点。
2、 保留A的左子树不变,将其右子树与最小左高树B合并,合并后的二叉树成为新的A的右子树。
3、 把二叉树转换为最小左高树从最后一个修改结点(注意:这里不是最后结点)开始,回溯到最终的树根结点,使得路径上的所有结点满足不等式:shortest(left_child())>= shortest(right_child())
程序:
函数定义:
#ifndef LEFTIST_TREE_H_INCLUDED#define LEFTIST_TREE_H_INCLUDED#include <malloc.h>#include<stdio.h>#include<stdlib.h>#define MAX_SIZE 11#define SWAP(x,y,t) ((t)=(x),(x)=(y),(y)=(t))typedef struct lefttree *LeftistTree;typedef struct lefttree{ LeftistTree left_child; LeftistTree right_child; int data; int shortest;}left_tree;void min_uion(LeftistTree*a,LeftistTree*b);void init_left_tree(LeftistTree *a,int data);void min_combine(LeftistTree *a,LeftistTree *b);void show_pre_tree( LeftistTree *a );/*初始化二叉树*/void init_left_tree(LeftistTree *b,int data){ if(!*b) { *b=(LeftistTree)malloc(sizeof(left_tree)); (*b)->data=data; (*b)->left_child=NULL; (*b)->right_child=NULL; (*b)->shortest=1; }}/*合并两棵树*/void min_combine(LeftistTree *a,LeftistTree *b){ if(!*a) *a=*b; else if(*b) min_uion(a,b); *b=NULL;}/*合并两棵最小左高树*/void min_uion(LeftistTree*a,LeftistTree*b){ LeftistTree temp=NULL; if((*a)->data>(*b)->data)//比较两棵树根结点大小 SWAP(*a,*b,temp); if(!(*a)->right_child)//右子树是否为空 (*a)->right_child=*b; else min_uion(&(*a)->right_child,b);//把a右子树和b合并 if(!(*a)->left_child) { (*a)->left_child=(*a)->right_child; (*a)->right_child=NULL; } else if((*a)->right_child->shortest>(*a)->left_child->shortest) SWAP((*a)->right_child,(*a)->left_child,temp); if(!(*a)->right_child) (*a)->shortest=1; else (*a)->shortest=(*a)->right_child->shortest+1;}/*先序递归遍历最小左高树*/void show_pre_tree(LeftistTree *a){ if (*a) { printf("%d ", (*a)->data ); show_pre_tree( &(*a)->left_child ); show_pre_tree( &(*a)->right_child ); }}#endif // LEFTIST_TREE_H_INCLUDED
程序测试:
#include "leftist_tree.h"int main(){ LeftistTree a=NULL; LeftistTree b=NULL; int i,data; for(i=1;i<MAX_SIZE-5;i++) { scanf("%d",&data); init_left_tree(&b,data); min_combine(&a,&b); } show_pre_tree(&a); return 0;}
- 数据结构——左高树(C语言)
- 数据结构——双端堆(C语言)
- 数据结构——二项堆(C语言)
- 数据结构——栈(c语言)
- 数据结构(c语言)—笔记
- 数据结构(C语言)
- 数据结构(二)——链表(C语言实现)
- 数据结构(三)——栈(C语言实现)
- 数据结构(四)——队列(C语言实现)
- 数据结构——链栈的实现(C语言)
- 数据结构——队列的链式实现(C语言)
- 数据结构——双向链表(C语言)
- 数据结构——二叉查找树(C语言)
- 数据结构课程设计——通讯录系统设计(C语言)
- 数据结构与算法(C语言描述)——单链表
- 数据结构与算法——二分查找(C语言)
- C语言学习总结(四)——数据结构
- 数据结构——顺序表实现(c语言)
- ORACLE 日期相关函数
- 批处理判断变量值是否为空的终极方法
- 如何调试makefile变量
- linux swap理解-为什么linux有足够的内存还进行swap
- linux驱动学习-4th
- 数据结构——左高树(C语言)
- Android Phone模块 一
- java jdom解析xml格式字符串
- JDK1.7新特性
- 易经六十四卦详解
- 【安卓笔记】自定义view之组合控件
- java的fuction!
- 面试技巧 (值得学习)
- public fianl中的java!