数据结构

数据结构部分

一. Array类的实现

#include <iostream>
#include <cassert>

template<typename T>
class Array{
private:
	T* data;
	int size;
	int capacity;
	void resize(int newCapacity){
		T* newData = new T[newCapacity];
		for(int i = 0; i < size; i++)
			newData[i] = data[i];
		data = newData;
		capacity = newCapacity;
	}
public:
	Array(int capacity){
		data = new T[capacity];
		size = 0;
		this->capacity = capacity;
	}
	Array(){
		data = new T[10];
		size = 0;
		capacity = 10;
	}
	~Array(){
		delete[] data;
	}
	int getCapacity(){
		return capacity;
	}
	int getSize(){
		return size;
	}
	bool isEmpty(){
		return size == 0;
	}
	void add(int index, T e){
		assert(index >=0 && index <= size);
		if(size == capacity)
			resize(2 * capacity);
		for(int i = size - 1; i >= index; i--)
			data[i + 1] = data[i];
		data[index] = e;
		size++;
	}
	void addFirst(T e){
		add(0, e);
	}
	void addLast(T e){
		add(size, e);
	}
	T get(int index){
		assert(index >= 0 && index < size);
		return data[index];
	}
	T getFirst(){
		return get(0);
	}
	T getLast(){
		return get(size - 1);
	}
	void set(int index, T e){
		assert(index >= 0 && index < size);
		data[index] = e;
	}
	bool contain(T e){
		for(int i = 0; i < size; i++)
			if(data[i] == e)
				return true;
		return false;
	}
	int find(T e){
		for(int i = 0; i < size; i++)
			if(data[i] == e)
				return i;
		return -1;
	}
	T remove(int index){
		assert(index >= 0 && index < size);
		T ret = data[index];
		for(int i = index; i < size - 1; i++)
			data[i] = data[i + 1];
		size--;
		if(size == capacity / 4 && capacity / 2 != 0)
			resize(capacity / 2);
		return ret;
	}
	T removeFirst(){
		return remove(0);
	}
	T removeLast(){
		return remove(size - 1);
	}
	void removeElement(T e){
		int index = find(e);
		if(index != -1)
			remove(index);
	}
}

二. Stack和Queue的实现

1. Stack

  • 接口类:Stack.h
template<typename T>
class Stack{
public:
	virtual int getSize() = 0;
	virtual bool isEmpty() = 0;
	virtual void push(T e) = 0;
	virtual void pop() = 0;
	virtual T front() = 0;
}
  • 实现类:ArrayStack.h
#include "Array.h"
#include "Stack.h"

template<typename T>
class ArrayStack : public Stack<T>{
private:
	Array<T>* array;
public:
	ArrayStack(int capacity){
		array = new Array<T>(capacity);
	}
	ArrayStack(){
		array = new Array<T>();
	}
	~ArrayStack(){
		delete[] array;
		array = nullptr;
	}
	int getSize() overide{
		return array->getSize();
	}
	bool isEmpty() overide{
		return array->isEmpty();
	}
	void push(T e) overide{
		array->addLast(e);
	}
	void pop() overide{
		array->removeLast();
	}
	T front() overide{
		return array->getLast();
	}	
}

2. Queue

  • 接口类:Queue.h
template<typename T>
class Queue{
public:
	virtual int getSize() = 0;
	virtual bool isEmpty() = 0;
	virtual void push(T e) = 0;
	virtual void pop() = 0;
	virtual T front() = 0;
}
  • 实现类:ArrayQueue.h(基于Array类)
#include "Array.h"
#include "Queue.h"

template<typename T>
class ArrayQueue : public Queue<T>{
private:
	Array<T>* array;
public:
	ArrayQueue(int capacity){
		array = new Array<T>(capacity);
	}
	ArrayQueue(){
		array = new Array<T>();
	}
	~ArrayQueue(){
		delete[] array;
		array = nullptr;
	}
	int getSize() overide{
		return array->getSize();
	}
	bool isEmpty() overide{
		return array->isEmpty();
	}
	void push(T e) overide{
		array->addLast(e);
	}
	void pop() overide{
		array->removeFirst();
	}
	T front() overide{
		return array->getFirst();
	}	
}
  • 实现类:LoopQueue.h(不基于Array类)
#include "Queue.h"

template<typename T>
class LoopQueue : public Queue<T>{
private:
	T* data;
	int front, tail;
	int capacity;
	void resize(int newCapacity){
		T* newData = new T[newCapacity]
		for(int i = 0; i < getSize(); i++)
			newData[i] = data[(i + front) % capacity];
		data = newData;
		front = 0;
		tail = getSize();
		capacity = newCapacity;
	}
public:
	LoopQueue(int capacity){
		data = new T[capacity];
		front = 0;
		tail = 0;
		this->capacity = capacity;
	}
	LoopQueue(){
		data = new T[10];
		front = 0;
		tail = 0;
		capacity = 10;
	}
	~LoopQueue(){
		delete[] data;
		array = nullptr;
	}
	int getSize() overide{
		return (tail + capacity - front) % capacity;
	}
	bool isEmpty() overide{
		return front == tail;
	}
	void push(T e) overide{
		if((tail + 1) % capacity == front)
			resize(2 * capacity);
		data[tail] = e;
		tail = (tail + 1) % capacity;
	}
	void pop() overide{
		assert(!isEmpty());
		front = (front + 1) % capacity;
		if(getSize() == capacity / 4 && capacity / 2 != 0)
			resize(capacity / 2);
	}
	T front() overide{
		assert(!isEmpty());
		return data[front];
	}	
}

三. LinkedList的实现

#include <iostream>

template<typename T>
class LinkedList{
private:
	struct Node{
		T e;
		Node* next;
		Node(T e, Node* next) : e(e), next(next){}
		Node(T e) : e(e), next(NULL){}
		Node() : next(NULL){}
	}
	Node* dummyHead;
	int size;
public:
	LinkedList(){
		dummyHead = new Node();
		size = 0;
	}
	~LinkedList(){
		while(dummyHead!= NULL){
			Node* node = dummyHead;
			dummyHead = dummyHead->next;
			delete node;
			size--;
		}
		assert(dummyHead== NULL && size == 0);
	}
	int size(){
		return size;
	}
	bool isEmpty(){
		return size == 0;
	}
	void insert(int index, T e){
		assert(index < 0 || index > size);
		Node* prev = dummyHead;
		for(int i = 0; i < index; i++)
			prev = prev ->next;	
		// 传统写法	
		//Node* insertNode = new Node(e);
		//insertNode->next = node->next;
		//node->next = insertNode;
		//炫酷写法
		prev->next = new Node(e, prev->next);
		size++;
	}
	void insertFirst(T e){
		insert(0, e);
	}
	void insertLast(T e){
		insert(size, e);
	}
	//获得链表的第index(0-based)个位置的元素
	T get(int index){
		assert(index < 0 || index >= size);
		Node curNode = dummyHead->next;
		for(int i = 0; i < index; i++)
			curNode = curNode->next;
		return curNode->e;
	}
	T getFirst(){
		return get(0);
	}
	T getLast(){
		return get(size - 1);
	}
	void set(int index, T e){
		assert(index < 0 || index >= size);
		Node* curNode = dummyHead->next;
		for(int i = 0; i < index; i++)
			curNode = curNode->next;
		curNode->e = e;
	}
	bool contain(T e){
		Node* curNode = dummyHead->next;
		while(curNode != NULL){
			if(curNode->e == e)
				return true;
			curNode = curNode->next;
		}
		return false;
	}
	void remove(int index){
		assert(index < 0 || index >= size);
		Node* prev = dummyHead;
		for(int i = 0; i < index; i++)
			prev = prev->next;
		Node* delNode = prev->next;
		prev->next = delNode->next;
		delete delNode;
		size--;
	}
	void removeFirst(){
		remove(0);
	}
	void removeLast(){
		remove(size - 1);
	}
	void removeElement(T e){
		Node* prev = dummyHead;
		while(prev->next != NULL){
			if(prev->next->e == e)
				break;
			prev = prev->next;
		}
		if(prev->next != NULL){
			Node* delNode = prev->next;
			prev->next = delNode->next;
			delete delNode;
			size--;
		}
	}
}

四. BST的实现

#include <iostream>
#include <queue>
#include <cassert>
using namespace std;

template<typename Key, typename Value>
class BST{
private:
	struct Node{
		Key key;
		Value value;
		Node* left;
		Node* right;
		Node(Key key, Value value){
			this->key = key;
			this->value = value;
			this->left = this->right = NULL;
		}
		Node(Node* node){
			this->key = node->key;
			this->value = node->value;
			this->left = node->left;
			this->right = node->right;
		}
	}
	Node* root; //根结点
	int count; //树中的结点个数
public:
	BST(){
		root = NULL;
		count = 0;
	}
	~BST(){
		destroy(root);
	}
	int size(){
		return count;
	}
	bool isEmpty(){
		return count == 0;
	}
	//向二分搜索树中插入一个新的(key, value)数据对
	void insert(Key key, Value value){
		root = insert(root, key, value);
	}
	bool contain(Key key){
		return contain(root, key);
	}
	//在二分搜索树中搜索key所对应的值。如果值不存在,则返回NULL
	Value* search(Key key){
		return search(root, key);
	}
	//二叉搜索树的前序遍历
	void preOrder(){
		preOrder(root);
	}
	//二叉搜索树的中序遍历
	void inOrder(){
		inOrder(root);
	}
	//二叉搜索树的后序遍历
	void postOrder(){
		postOrder(root);
	}
	//二叉搜索树的层次遍历
	void levelOrder(){
		if(root == NULL)
			return;
		queue<Node*> q;
		q.push(root);
		while(!q.empty()){
			Node* node = q.front();
			q.pop();
			cout << node->key;
			if(node->left)
				q.push(node->left);
			if(node->right)
				q.push(node->right);
		}
	}
	// 寻找二分搜索树最小的键值
	Key minimum(){
		assert(count != 0);
		Node* minNode = minimum(root);
		return minNode->key;
	}
	// 寻找二分搜索树最大的键值
	Key maximum(){
		assert(count != 0);
		Node* maxNode = maximum(root);
		return maxNode->key;
	}
	// 从二分搜索树中删除最小值所在的结点
	void removeMin(){
		if(root)
			root = removeMin(root);
	}
	// 从二分搜索树中删除最大值所在的结点
	void removeMax(){
		if(root)
			root = removeMax(root);
	}
	// 从二叉搜索树中删除键值为key的结点
	void remove(Key key){
		root = remove(root, key);
	}
private:
	//在以node为根的二叉搜索树中插入(key, value)数据对,并返回新的根
	Node* insert(Node* node, Key key, Value value){
		if(node == NULL){
			count++;
			return new Node(key, value);
		}
		if(key == node->key)
			node->value = value;
		else if(key < node->key)
			node->left = insert(node->left, key, value);
		else  //key > node->key
			node->right = insert(node->right, key, value);
		return node;
	}
	bool contain(Node* node, Key key){
		if(node == NULL)
			return false;
		if(key == node->key)
			return true;
		else if(key < node->key)
			return contain(node->left, key);
		else // key > node->key
			return contain(node->right, key);
	}
	Value* search(Node* node, Key key){
		if(node == NULL)
			return NULL;
		if(key == node->key)
			return &(node->value);
		else if(key < node->key)
			return search(node->left, key);
		else // key > node->key
			return search(node->right, key);
	}
	void preOrder(Node* node){
		if(node == NULL)
			return;
		cout << node->value;
		preOrder(node->left);
		preOrder(node->right);
	}
	void inOrder(Node* node){
		if(node == NULL)
			return;
		inOrder(node->left);
		cout << node->value;
		inOrder(node->right);
	}
	void postOrder(Node* node){
		if(node == NULL)
			return;
		postOrder(node->left);
		postOrder(node->right);
		cout << node->value;
	}
	//释放以node为根的二叉搜索树的所有结点
	void destroy(Node* node){
		if(node == NULL)
			return;
		destroy(node->left);
		destroy(node->right);
		delete node;
		count--;
	}
	Key minimum(Node* node){
		if(node->left == NULL)
			return node;
		return minimum(node->left);
	}
	Key maximum(Node* node){
		if(node->right == NULL)
			return node;
		return maximum(node->right);
	}
	Node* removeMin(Node* node){
		if(node->left == NULL){
			Node* rightNode = node->right;
			delete node;
			count--;
			return rightNode;
		}
		node->left = removeMin(node->left);
		return node;
	}
	Node* removeMax(Node* node){
		if(node->right == NULL){
			Node* leftNode = node->left;
			delete node;
			count--;
			return leftNode;
		}
		node->right = removeMax(node->right);
		return node;
	}
	Node* remove(Node* node){
		if(node == NULL)
			return NULL;
		if(key < node->key){
			node->left = remove(node->left);
			return node;
		}
		else if(key > node->key){
			node->right = remove(node->right);
			return node;
		}
		else { //key == node->key
			if(node->left == NULL){
				Node* rightNode = node->right;
				delete node;
				count--;
				return rightNode;
			}
			if(node->right == NULL){
				Node* leftNode = node->left;
				delete node;
				count--;
				return leftNode;
			}
			// node左右子树均不为空
			node* successor = new Node(minimum(node->right));
			count++;
			successor->right = removeMin(node->right);
			successor->left = node->left;
			delete node;
			count--;
			return successor;
		}
	}
}

五. maxHeap的实现

#include <iostream>
#include <cassert>
using namespace std;

template<typename Item>
class MaxHeap{
private:
	Item* data;
	int count;
public:
	// 构造函数, 构造一个空堆, 可容纳capacity个元素
	MaxHeap(int capacity){
		data = new Item[capacity + 1];
		count = 0;
	}
    // 构造函数, 通过一个给定数组创建一个最大堆(heapify)
    // 该构造堆的过程, 时间复杂度为O(n)
    MaxHeap(Item arr[], int n){
    	data = new Item[n + 1];
    	capacity = n;
    	for(int i = 0; i < n; i++)
    		data[i + 1] = arr[i];
    	count = n;
    	for(int i = parent(count); i >= 1; i--)
    		shiftDown(i);
    }
	~MaxHeap(){
		delete[] data;
	}
	int size(){
		return count;
	}
	bool isEmpty(){
		return count == 0;
	}
	void insert(Item item){
		assert(count + 1 <= capacity);
		data[count + 1] = item;
		shiftUp(count + 1);
		count++;
	}
	Item extractMax(){
		assert(count > 0);
		Item ret = data[1];
		swap(data[1], data[count]);
		count--;
		shiftDown(1);
		return ret;
	}
	Item getMax(){
		assert(count > 0);
		return data[1];
	}
private:
	void parent(int k){
		assert(k > 1);
		return k / 2;
	}
	void left(int k){
		return 2 * k;
	}
	void right(int k){
		return 2 * k + 1;
	}
	void shiftUp(int k){
		Item e = data[k];
		while(k > 1 && data[k] > data[parent(k)]){
			//swap(data[k], data[parent(k)]);
			data[k] = data[parent(k)];
			k = parent(k);
		}
		data[k] = e;
	}
	void shiftDown(int k){
		Item e = data[k];
		while(left(k) <= count){
			int j = left(k);
			if(right(k) <= count && data[right(k)] > data[left(k)]) 
				j = right(k);
			if(data[k] >= data[j])
				break;
			//swap(data[k], data[j]);
			data[k] = data[j];
			k = j;
		}
		data[k] = e;
	}
}

六. UnionFind的实现

一共有五个版本的unionFind:quickFind,quickUnion,基于size的优化,基于rank的优化,基于路径压缩的优化最终版

version 1:quickFind

#include <iostream>
#include <cassert>
using namespace std;

class UnionFind1{
private:
	int* id; //第一个版本的unionFind本质就是一个数组
	int count; //数据个数
public:
	UnionFind1(int n){
		count = n;
		id = new int[n];
		for(int i = 0; i < n; i++)
			id[i] = [i];
	}
	~UnionFind1(){
		delete[] id;
	}
	int find(int p){
		assert(p >= 0 && p < count);
		return id[p];
	}
	bool isConnected(int p, int q){
		return find(p) == find(q);
	}
	void unionElements(int p, int q){
		int pID = find(p);
		int qID = find(q);
		if(pID == qID)
			return;
		for(int i = 0; i < count; i++)
			if(id[i] == pID)
				id[i] = qID;
	}
}

version 2:quickUnion

class UnionFind2{
private:
	//第二版的unionFind,使用一个数组构建一棵指向父结点的树
	int* parent; //parent[i]表示第i个元素所指向的父结点
	int count; //数据个数
public:
	UnionFind2(int n){
		count = n;
		parent = new int[n];
		for(int i = 0; i < n; i++)
			parent[i] = i;
	}
	~UnionFind2(){
		delete[] parent;
	}
    // 查找过程, 查找元素p所对应的集合编号. O(h)复杂度, h为树的高度
	int find(p){
		assert(p >= 0 && p < count);
		while(p != parent[p])
			p = parent[p];
		return p;
	}
	bool isConnected(int p, int q){
		return find(p) == find(q);
	}
	void unionElements(int p, int q){
		int pRoot = find(p);
		int qRoot = find(q);
		if(pRoot == qRoot)
			return;
		parent[pRoot] = qRoot;
	}
}

version 3:quickUnion + size优化

class UnionFind3{
private:
	int* parent;
	int* sz; //sz[i]表示以i为根的集合中元素个数
	int count;
public:
	UnionFind3(int n){
		count = n;
		parent = new int[n];
		sz = new int[n];
		for(int i = 0; i < n; i++){
			parent[i] = i;
			sz[i] = 1;
		}
	}
	~UnionFind3(){
		delete[] parent;
		delete[] sz;
	}
	int find(p){
		assert(p >= 0 && p < count);
		while(p != parent[p])
			p = parent[p];
		return p;
	}
	bool isConnected(int p, int q){	
		return find(p) == find(q);
	}
	void unionElements(int p, int q){
		int pRoot = find(p);
		int qRoot = find(q);
		if(pRoot == qRoot)
			return;
        // 根据两个元素所在树的元素个数不同判断合并方向
        // 将元素个数少的集合合并到元素个数多的集合上
		if(sz[pRoot] < sz[qRoot]){
			parent[pRoot] = qRoot;
			sz[qRoot] += sz[pRoot];
		}
		else { //sz[pRoot] >= sz[qRoot]
			parent[qRoot] = pRoot;
			sz[pRoot] += sz[qRoot];
		}
	}
}

version 4:quickUnion + rank优化

class UnionFind4{
private:
	int* parent;
	int* rank; //rank[i]表示以i为根的树的高度
	int count;
public:
	UnionFind4(int n){
		count = n;
		parent = new int[n];
		rank = new int[n];
		for(int i = 0; i < n; i++){
			parent[i] = i;
			rank[i] = 1;
		}
	}
	~UnionFind4(){
		delete[] parent;
		delete[] rank;
	}
	int find(p){
		assert(p >= 0 && p < count);
		while(p != parent[p])
			p = parent[p];
		return p;
	}
	bool isConnected(int p, int q){	
		return find(p) == find(q);
	}
	void unionElements(int p, int q){
		int pRoot = find(p);
		int qRoot = find(q);
		if(pRoot == qRoot)
			return;
        // 根据两个元素所在树的高度不同判断合并方向
        // 将高度低的集合合并到高度高的集合上
		if(rank[pRoot] < rank[qRoot])
			parent[pRoot] = qRoot;
		else if(rank[qRoot] < rank[pRoot])
			parent[qRoot] = pRoot;
		else{ // rank[pRoot] == rank[qRoot]
			parent[pRoot] = qRoot;
			rank[qRoot] += 1; //此时维护rank的值
		}
	}
}

version 5:quickUnion + rank优化 + 路径压缩

class UnionFind5{
private:
	int* parent;
	int* rank; //rank[i]表示以i为根的树的高度
	int count;
public:
	UnionFind5(int n){
		count = n;
		parent = new int[n];
		rank = new int[n];
		for(int i = 0; i < n; i++){
			parent[i] = i;
			rank[i] = 1;
		}
	}
	~UnionFind5(){
		delete[] parent;
		delete[] rank;
	}
	int find(p){
		assert(p >= 0 && p < count);
		while(p != parent[p]){
			parent[p] = parent[parent[p]]; // path compression 1
			p = parent[p];
		}
		return p;
        //if( p != parent[p] )   // path compression 2, 递归算法
        //    parent[p] = find( parent[p] );
        //return parent[p];
	}
	bool isConnected(int p, int q){	
		return find(p) == find(q);
	}
	void unionElements(int p, int q){
		int pRoot = find(p);
		int qRoot = find(q);
		if(pRoot == qRoot)
			return;
        // 根据两个元素所在树的高度不同判断合并方向
        // 将高度低的集合合并到高度高的集合上
		if(rank[pRoot] < rank[qRoot])
			parent[pRoot] = qRoot;
		else if(rank[qRoot] < rank[pRoot])
			parent[qRoot] = pRoot;
		else{ // rank[pRoot] == rank[qRoot]
			parent[pRoot] = qRoot;
			rank[qRoot] += 1; //此时维护rank的值
		}
	}
}

七. hashTable的实现

#include <iostream>
#include <map>

template<typename Key, typename Value>
class HashTable{
private:
	int M;
	int size;
	map<Key, Value>** hashTable;
	int hash(Key key){
		return (hashCode(key) & 0x7fffffff) % M;
	}
	int hashCode(Key key){
		std::hash<Key> key_hash;
		return key_hash(key);
	}
public:
	HashTable(int M){
		this->M = M;
		size = 0;
		hashTable = new map<Key, Value>*[M];
		for(int i = 0; i < M; i++)
			hashTable[i] = new map<Key, Value>();
	}
    HashTable() {
        this->M = 97;
        size = 0;
        hashTable = new map<Key, Value>*[M];
        for (int i = 0; i < M; ++i)
            hashTable[i] = new map<Key, Value>();
    }
    int size(){
    	return size;
    }
    void insert(Key key, Value value){
    	map<Key, Value>* mp = hashTable[hash(key)];
    	if(mp->find(key) != mp->end())
    		mp[key] = value;
    	else{
    		mp->insert(key, value);
    		size++;
    	}
    }
    void remove(Key key){
    	map<Key, Value>* mp = hashTable[hash(key)];
    	if(mp->find(key) != mp->end()){
    		mp.erase(key);
    		size--;
    	}
    }
    void set(Key key, Value value){
    	map<Key, Value>* mp = hashTable[hash(key)];
    	assert(mp->find(key) != mp->end());
    	mp[key] = value;	
    }
    bool contain(Key key){
    	map<Key, Value>* mp = hashTable[hash(key)];
    	return mp->find(key) != mp->end() ? true : false;
    }
    Value get(Key key){
    	map<Key, Value>* mp = hashTable[hash(key)];
    	assert(mp->find(key) != mp->end());
    	return mp[key];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值