树的一些操作

  1 #include <iostream>
  2 #include <cmath>
  3 #include <queue>
  4 #include <stack>
  5 using namespace std;
  6
  7 struct Treenode
  8 {
  9     int data;
 10     Treenode *left, *right;
 11 };
 12 // 求树高
 13 int height(Treenode* root)
 14 {
 15     if(!root)
 16         return 0;
 17     int leftHeight=height(root->left);
 18     int rightHeight=height(root->right);
 19
 20     return (leftHeight>rightHeight)?leftHeight+1:rightHeight+1;
 21 }
 22
 23 // 判断是否平衡二叉树
 24 /*
 25 平衡二叉树的子树也都是平衡的
 26 */
 27 bool IsBlance(Treenode* root)
 28 {
 29     if(!root)
 30         return true;
 31     int leftHeight=height(root->left);
 32     int rightHeight=height(root->right);
 33     int diff=leftHeight-rightHeight;
 34     if(abs(diff)>1)
 35         return false;
 36     return IsBlance(root->left) && IsBlance(root->right);
 37 }
 38
 39 // 判断是否完全二叉树
 40 // 层次遍历,出现空节点后面应该都是NULL
 41 bool IsComplate(Treenode* root)
 42 {
 43     if(!root)
 44         return true;
 45     queue<Treenode*>q;
 46     bool flag=true; // 若出现NULL后继置为false
 47     q.push(root);
 48     while(!root)
 49     {
 50         Treenode* p=q.front();
 51         q.pop();
 52         if(p->left && flag)q.push(p->left);
 53         else if(p->left) return false;
 54         else flag=false;
 55
 56         if(p->right && flag)q.push(p->right);
 57         else if(p->right) return false;
 58         else flag=false;
 59     }
 60     return true;
 61 }
 62
 63 // 判断是否BST二叉排序树
 64 //中序遍历,是从小到大有序排列
 65 bool IsSort(Treenode* root)
 66 {
 67     if(!root)
 68         return true;
 69     stack<Treenode*>s;
 70     Treenode* p=root;
 71     Treenode* pre=NULL;  // 记录中序遍历的前一个节点
 72     while(p || !s.empty())
 73     {
 74         while(p)    // 走左子树
 75         {
 76             s.push(p);
 77             p=p->left;
 78         }
 79         if(!s.empty())
 80         {
 81             p=s.top(); //弹出最左边的节点
 82             s.pop();
 83             if(pre && pre->left > p->left) return false;
 84             pre=p;
 85             p=p->left;
 86         }
 87     }
 88     return true;
 89 }
 90
 91 //树的遍历
 92 //递归
 93 void PreOrder(Treenode* root)
 94 {
 95     if(!root)
 96         return;
 97     cout<<root->data;
 98     PreOrder(root->left);
 99     PreOrder(root->right);
100 }
101
102 void InOrder(Treenode* root)
103 {
104     if(!root)
105         return;
106     InOrder(root->left);
107     cout<<root->data;
108     InOrder(root->right);
109 }
110
111 void PostOrder(Treenode* root)
112 {
113     if(!root)
114         return;
115     PostOrder(root->left);
116     PostOrder(root->right);
117     cout<<root->data;
118 }
119
120 // 非递归
121 void LevelOrder(Treenode* root)
122 {
123     if(!root)
124         return;
125     queue<Treenode*>q;
126     q.push(root);
127     while(!q.empty())
128     {
129         Treenode* p=q.front();q.pop();
130         cout<<p->data;
131         if(p->left)q.push(p->left);
132         if(p->right)q.push(p->right);
133     }
134 }
135
136 void PreOrder2(Treenode* root)
137 {
138     if(!root)
139         return;
140     stack<Treenode*>q;
141     Treenode* p=root;
142     while(p || !q.empty())
143     {
144         while(p) // 一直往左分支走
145         {
146             cout<<p->data;
147             q.push(p);
148             p=p->left;
149         }
150         if(!q.empty()) //回溯一步往右走
151         {
152             p=q.top();
153             q.pop();
154             p=p->right;
155         }
156     }
157 }
158
159 void InOrder2(Treenode* root)
160 {
161     if(!root)
162         return;
163     stack<Treenode*>q;
164     Treenode* p=root;
165     while(p || !q.empty())
166     {
167         while(p)
168         {
169             q.push(p);
170             p=p->left;
171         }
172         if(!q.empty()) // 退栈走右子树
173         {
174             p=q.top();
175             q.pop();
176             cout<<p->data;
177             p=p->right;
178         }
179     }
180 }
181
182 void PostOrder2(Treenode* root) //***想通
183 {
184     if(!root)
185         return;
186     stack<Treenode*>s;
187     Treenode* p=root;
188     Treenode* q=NULL;
189     while(p || !s.empty())
190     {
191         while(p)
192         {
193             s.push(p);
194             p=p->left;
195         }
196         if(!s.empty())
197         {
198             p=s.top();
199             if(p->right==NULL || p->right==q)// p是叶子节点或p是刚打印节点的中间节点
200             {
201                 cout<<p->data;
202                 q=p; // 记录返回时要用的中间节点
203                 s.pop();
204                 p=NULL;
205             }
206             else
207                 p=p->right; // p不是叶子节点,不出栈,往右走
208         }
209     }
210 }

时间: 2024-08-09 22:02:08

树的一些操作的相关文章

Geeks Splay Tree Insert 树的插入操作

Splay树的插入操作,只需要处理好插入节点的孩子节点就可以了,最重要的是不要破坏了BST的基本规则. 因为高度并不是Splay树的首要因素,所以插入的时候也是使用splay操作,然后在根节点插入. 参考:http://www.geeksforgeeks.org/splay-tree-set-2-insert-delete/ 对比一下使用插入创建的树和手工创建数的区别,先序遍历的结果: #pragma once #include<stdio.h> #include <stdlib.h&g

线段树区间更新操作及Lazy思想(详解)

此题题意很好懂:  给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求和 介绍Lazy思想:lazy-tag思想,记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率. 在此通俗的解释我理解的Lazy意思,比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果

Splay伸展树入门(单点操作,区间维护)

ps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是一颗二叉搜索树,刚刚开始学的时候找题hash数字的题先测板子... 后来那题被学长改了数据不能用平衡树测了...一道二分数字的题. 二叉搜索树的功能是,插入一个数字,在O(logn)的时间内找到它,并操作,插入删除等.但是可能会让二叉搜索树退化成链,复杂度达到O(n) 原文地址:https://www.c

UVa 11992 Fast Matrix Operations(线段树双懒操作,二维转一维)

题意:给个r*c的矩形,三种操作,将一个子矩形权值+v,将一个子矩阵权值赋值为v,查询一个子矩阵sum,max,min.起初矩阵权值为0,保证r<=20,r*c<=1e6,操作次数不超过10000 链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18697 题解:将二维转一维,设当前点为(x,y),则它在线段树上的点为(x-1)*c+y,由于行不超过20行,不妨枚举每一行,去操作.对于一维的线段树,要进行赋值,加法

AVL树的插入操作(旋转)图解

=================================================================== AVL树的概念 在说AVL树的概念之前,我们需要清楚二茬搜索树的概念.对于二叉搜索树,我们知道它可以降低查找速率,但是如果一个二叉搜索树退化成一棵只剩单支的搜索树,此时的查找速率就相当于顺序表中查找元素,效率变低,时间复杂度由原来的O(logN)变为O(N). 此时就有了AVL(高度平衡二叉搜索树),从它的名字就能知道它也是一棵二叉搜索树,只是它在插入元素的时候

数据结构——树的简单操作集合

非常多数据结构的书上解说数据机构时都是採用伪代码实现.事实上感觉蛮不直观的.所以对于全部的数据结构操作我都将其用C实现一遍. 树是学习二叉树的基础,也是后面理解B树.B+树的等树的基础,以下就给出树的几个简单操作,方便理解. 数据结构 //-------数据结构---------------------------------------- #define m 3 //定义度为3的树 typedef char datatype; typedef struct node { datatype da

树的简单操作集合——基于C实现

很多数据结构的书上讲解数据机构时都是采用伪代码实现,其实感觉蛮不直观的,所以对于所有的数据结构操作我都将其用C实现一遍. 树是学习二叉树的基础,也是后面理解B树,B+树的等树的基础,下面就给出树的几个简单操作,方便理解. 数据结构 //-------数据结构---------------------------------------- #define m 3 //定义度为3的树 typedef char datatype; typedef struct node { datatype data

Splay树(多操作)——POJ 3580 SuperMemo

对应POJ题目:点击打开链接 SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11309   Accepted: 3545 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a

构建伸展树的伸展操作

以下结果与书中描述略有出入,因为书中没有给出代码示例,因此只能认为本人的结果与书中描述的现象大致相似: 主要的函数:查找函数(同时伸展): 1 ETree *findNode(ETree *&root,const int &data) 2 { 3 ETree *tmp; 4 ETree *k1, *k2, *k3; 5 if (root == nullptr) 6 return root; 7 8 //三种主要情况 9 if (root->data == data) 10 retur

poj 3667 Hotel (线段树的合并操作)

Hotel The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and enjoy a vacation on the sunny shores of Lake Superior. Bessie, ever the competent travel agent, has named the Bullmoose Hotel on famed Cumberland Street as t