数据结构部分
一. 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];
}
}