template
class BSTNode :public BinNode {
private:
Key key;
E item;
BSTNode* lc;
BSTNode* rc;
public:
BSTNode() { lc = rc = NULL; }
BSTNode(Key k, E it, BSTNode* lc=NULL, BSTNode* rc=NULL) {
key = k; item = it;
this.lc =
结点:包含一个数据元素及若干指向子树的分支
子结点:结点的子树的根称为该结点的孩子
父结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲
祖先:从根到该结点的所经分支上的所有结点
后代:以某结点为根的子树中任一结点都称为该结点的子孙
结点的度:结点子树的个数
叶子结点:也叫终端结点,是度为 0 的结点;
内部结点:度不为0的结点
结点层:根结点的层定义为0(外国教材),中文教材定义为1
深度:树中最大的结点层
高度:从1开始
二.特殊二叉树分类:
(1)满二叉树(full binary tree) :除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树
两个定理:a. 叶子结点的数目总比内部结点多1(数学归纳法)
b. 空子树的数目比叶子结点的数目多1
(2)完全二叉树(complete bianary tree): 若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布
三. Binaru Tree Node ADT
class BinNode {
public:
virtual ~BinNode() {}
virtual E& element() = 0;
virtual void setElement(const E&) = 0;
virtual BinNode* left() const = 0;
virtual void setLeft(BinNode*) = 0;
virtual BinNode* right()const = 0;
virtual void setRight(BinNode*) = 0;
virtual bool isLeaf() = 0;
};
( 1 ) 顺序存储结构
有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
若I为结点编号则 如果I>1,则其父结点的编号为I/2;
如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无左儿子;
如果2*I+1<=N,则其右儿子的结点编号为2*I+1;若2*I+1>N,则无右儿子。
(2)链式存储结构
template
class BSTNode :public BinNode {
private:
Key key;
E item;
BSTNode* lc;
BSTNode* rc;
public:
BSTNode() { lc = rc = NULL; }
BSTNode(Key k, E it, BSTNode* lc=NULL, BSTNode* rc=NULL) {
key = k; item = it;
this.lc = lc; this.rc = rc;
}
~BSTNode() {}
E& element() {
return item;
}
void setElement(const E& it) { item = it; }
Key& getkey() {
return key;
}
void setKey(Key& k) { key = k;}
BSTNode* left()const { return lc; }
void setLeft(BinNode* l) { lc = (BSTNode*)l; }
BSTNode* right()const { return rc; }
void setRight(BinNode* r) { rc = (BSTNode*)r; }
bool isLeaf() {
return (lc == NULL) && (rc == NULL);
}
};
template
void preorder(BinNode* root) {
if (root == 0) return;
cout << root->element() << " ";
if(root->left()!=NULL) preorder(root->left());
if(root->right()!=NULL) preorder(root->right());
}
五. 用二叉树来实现二叉搜索树(Binary Search Tree )
//Binary Search Tree
template
class BST {
private:
BSTNode* root;
int nodecount;
//插入并返回插入点的根结点,递归
BSTNode* inserthelp(BSTNode* root, const K& key, const E& elem) {
if (root == NULL) return new BSTNode(key, elem);
else if (root->getkey() > key) root->setLeft(inserthelp(root->left(), key, elem));
else root->setRight(inserthelp(root->right(), key, elem));
return root;
}
//递归
E findhelp(BSTNode* root, const K& key) {
if (root == NULL) return;
else if (root->getkey() > key) return findhelp(root->left(), key);
else if (root->getkey() < key) return findhelp(root->right(), key);
else return root->element;
}
//删除最小值,不断往左边递归就好,返回删除的最小值后的该处应该放置的结点
BSTNode* deletemin(BSTNode*rt) {
if (rt->left() == NULL) {
BSTNode* rightnode = rt->right();
delete rt;
return rightnode;
}
else {
rt->setLeft(deletemin(rt->left()));
return rt;
}
}
BSTNode getmin(BSTNode* rt) {
if (rt->left() == NULL)
return rt;
else return getmin(rt->left());
}
//根据key值删除结点
BSTNode removehelp(BSTNode* root, const K& key) {
if (root == NULL) return NULL;
else if (key < root->getkey()) removehelp(root->left(), key);
else if (key > root->getkey()) removehelp(root->right(), key);
else {
BSTNode* temp = root;
if (root->left() == NULL) {//左结点为空
root=root->right();
delete temp;
}
else if (root->right() == NULL) {//右结点为空
root = root->left();
delete temp;
}
else {//左右结点均不为空
temp = getmin(root->right());
root->setElement(temp->element);
root->setKey(temp->key());
root->setRight(deletemin(root->right()));
delete temp;
}
}
return root;
}
public:
BST() {
root = NULL;
nodecount = 0;
}
void insert(const K& key, const E& elem) {
root = inserthelp(root, key, elem);
nodecount++;
}
E find(const K& key) {
return findhelp(root, key);
}
int size() { return nodecount; }
E removeAny() {
if (root == NULL) return NULL;
else {
E temp = root->element;
root = removehelp(root, root->getkey());
nodecount--;
return temp;
}
}
};
六. 用二叉树来实现二叉堆(Binary Heap )
完全二叉堆具有堆的性质,所以一般用二叉树的顺序存储结构来实现二叉堆
//最大值堆
class Heap {
private:
int* heap;
int maxSize;
int n;
void shiftdown(int pos) {
//不断向下调整位置
while (!isLeaf(pos)) {
int lc = leftchild(pos);
if ((lc + 1 < n) && (heap[lc] < heap[lc + 1])) lc + 1;
if (heap[pos] > heap[lc]) break;
swap(heap[pos], heap[lc]);
pos = lc;
}
}
public:
Heap(int n=100) {
maxSize = n;
heap = new int[maxSize];
n = 0;
}
Heap(int* h, int num, int ms) {
heap = h;
n = num;
maxSize = ms;
buildHeap();
}
int size() { return n; }
bool isLeaf(int pos) {
if ((pos >= n / 2) && (pos < n))
return true;
else
return false;
}
int leftchild(int pos) {
assert(pos < n / 2);
return pos * 2+1;
}
int rightchild(int pos) {
assert(pos < n / 2);
return pos * 2 + 2;
}
int parent(int pos) {
assert(pos > 0);
return (pos - 1) / 2;
}
void buildHeap() {
//从最后一个内部结点开始往回,每一个都要shiftdown操作
for (int i = (n / 2 - 1); i >= 0; i--) {
shiftdown(i);
}
}
void insert(const int& it) {
assert(n <= maxSize);
heap[n] = it;
int curr=n++;
while (curr > 0 && (heap[curr] > heap[parent(curr)])){
swap(heap[curr], heap[parent(curr)]);
curr = parent(curr);
}
}
int removefirst() {
assert(n > 0);
int max = heap[0];
swap(heap[0], heap[--n]);
if (n != 0) shiftdown(0);
return max;
}
int remove(int pos) {
assert((pos < n) && (pos >= 0));
if (pos == (n - 1)) { return heap[--n]; }
else {
swap(heap[pos], heap[--n]);
while ((pos != 0) && (heap[pos] > heap[parent(pos)])) {
swap(heap[pos], heap[parent(pos)]);
pos = parent(pos);
}
}
if (pos != 0) shiftdown(pos);
return heap[n];
}
};