数据结构与算法分析-C++描述 第6章 斜堆ADT(SkewHeap)

斜堆(SkewHeap):

       斜堆是左式堆的自调节形式,斜堆和左式堆的关系类似于伸展树和AVL树的关系。斜堆是具有堆序的二叉树,但是不存在对树的结构限制,且不保留零长路径的信息。斜堆的右路径在任何时刻都可以任意长,因此所有操作最坏运行情况为O(N),正如伸展树一样,可以证明(还没证明出来 (┭┮﹏┭┮))对任意M次操作,总的最坏运行情况为O(M \log N),因此每次操作的摊还开销(amortized cost)O(\log N).

斜堆的基本操作:

       合并(merge):插入只是合并一种特殊情况;                       

                                    1. 如果两个堆有一个是空堆,可以直接返回非空堆;

                                    2.递归合并具有较大根节点的堆和较小根节点的右子堆;

                                    3.交换新堆根节点的左右孩子(交换较小根节点的堆的左右孩子并更新零长路径为左式堆操作)

合并图示:

数据结构与算法分析-C++描述 第6章 斜堆ADT(SkewHeap)_第1张图片数据结构与算法分析-C++描述 第6章 斜堆ADT(SkewHeap)_第2张图片

                                两个斜堆H_1H_2                                                                                  将H_2H_1右子堆合并 

数据结构与算法分析-C++描述 第6章 斜堆ADT(SkewHeap)_第3张图片

                                                                                       合并H_2H_1之后的结果

实例:在左式堆的基础上建立斜堆堆,实现插入、删除最小值、查询最小值、打印输出等功能。【注:此处为最小堆方式】

1、heap.h

//heap.h
#ifndef HEAP_H_
#define HEAP_H_

#include
#include
#include

using std::cout;
using std::endl;
using std::vector;

template
struct SkewNode{
	T element;
	SkewNode *left;
	SkewNode *right;
	
	SkewNode(const T &e, SkewNode *l = NULL, SkewNode *r = NULL):element(e), left(l), right(r){
	};
};

template
class SkewHeap{
public:
	//LeftistHeap constuctor
	SkewHeap():root(NULL){
	
	};
	
	//LeftistHeap constuctor
	SkewHeap(const SkewHeap &heap){
		root = clone(heap -> root);
	};
	
	//LeftistHeap destructor
	~SkewHeap(){
		makeEmpty();
	};
	
	//judge whether the heap is empty
	bool isEmpty() const{
		return root == NULL;
	};
	
	//find the minmum element in heap
	const T &findMin() const{
		if(root != NULL){
			return root -> element;
		}
		return (T)NULL;
	};
	
	//insert value
	void insert(const T &value){
		SkewNode* temp;
		temp = new SkewNode(value, NULL, NULL);
		root = merge(root, temp);
	};
	
	//delete the minmum
	void deleteMin(){
		if(isEmpty()){
			cout << " the heap is already empty !" << endl;
		}
		SkewNode *node = root;
		root = merge(root -> left, root -> right);
		delete node;
	};
	
	//delete the minItem
	void deleteMin(T &minItem){
		minItem = findMin();
		deleteMin();
	}
	
	//make empty of the heap
	void makeEmpty(){
		reclaimMemory(root);
		root = NULL;
	};
	
	//excute merge operation
	void merge(SkewHeap *heap){
		root = merge(root, heap -> root);
	};
	
	const SkewHeap & operator=(const SkewHeap &heap){
		if(this != &heap){
			makeEmpty();
			root = clone(heap.root);
		}
		return *this;
	};
	
	//print the heap
	void print(){
		SkewHeap heap;
		vector v;
		while(this -> root){
			v.push_back(this -> findMin());
			heap.insert(this -> findMin());
			this -> deleteMin();
		}
		for(int i = 0; i < v.size(); i++){
			cout << v[i] << " ";
		}
		cout << endl;
		*this = heap;
		
	};
	
private:
	SkewNode* merge(SkewNode* &h1, SkewNode* &h2);
	void swapChildren(SkewNode* &h1, SkewNode* &h2);
	void reclaimMemory(SkewNode *heap);
	SkewNode* clone(const SkewNode *heap);
private:
	SkewNode* root;
};

//merge root
template
SkewNode* SkewHeap::merge(SkewNode* &h1, SkewNode* &h2){
	if(h1 == NULL){
		return h2;
	}
	if(h2 == NULL){
		return h1;
	}
	if(h1 -> element > h2 -> element){
		swapChildren(h1, h2);
	}
	SkewNode* temp = merge(h1 -> right, h2);
	h1 -> right = h1 -> left;
	h1 -> left = temp;
	return h1;
}

template
void SkewHeap::swapChildren(SkewNode* &h1, SkewNode* &h2){
	SkewNode* temp = h1; 
	h1 = h2;
	h2 = temp;
}

template
void SkewHeap::reclaimMemory(SkewNode *heap){
	if(heap != NULL){
		reclaimMemory(heap -> left);
		reclaimMemory(heap -> right);
		delete heap;
	}
}

template
SkewNode* SkewHeap::clone(const SkewNode *heap){
	if(heap == NULL){
		return NULL;
	}
	return new SkewNode(heap -> element, clone(heap -> left), clone(heap -> right));
}

#endif

 

2、main.cpp

//main.cpp
#include
#include"heap.h"

using namespace std;

int main(){
	int arr1[8] = {3, 10, 8, 21, 14, 17, 23, 26};
	int arr2[8] = {6, 12, 7, 18, 24, 37, 18, 33};
	SkewHeap *h1 = new SkewHeap();
	SkewHeap *h2 = new SkewHeap();
	
	cout << "********* insert ************" << endl;
	for(int i = 0; i < 8; i++){
		h1 -> insert(arr1[i]);
		h2 -> insert(arr2[i]);
	}
	
	cout << "********* print ************" << endl;
	cout << " the info in h1 as follows : " << endl;
	h1 -> print();
	cout << " the info in h2 as follows : " << endl;
	h2 -> print();
	
	cout << "********* merge ************" << endl;
	h1 -> merge(h2);
	h1 -> print();
	
	cout << "********* deleteMin ************" << endl;
	int minItem;
	h1 -> deleteMin(minItem);
	cout << " the minmum value in h1 is " << minItem << endl;
	
	cout << " done ." << endl;
	return 0;
}

 

practice makes perfect ! 

你可能感兴趣的:(C++,数据结构与算法分析-C++描述)