您的位置:首页 > 理论基础 > 数据结构算法

常用数据结构和算法基础

2012-03-22 22:28 435 查看
template<class Object>
class List
{
private:
struct Node                 //double link
{
Node(const Object& orig = Object(),Node* p = NULL,Node* d = NULL):mb(orig),
prev(p),next(d){}
Object mb;
Node *prev;
Node *next;
};
public:
class const_iterator
{
public:
bool operator != (const const_iterator& orig)
{
return (current != orig.current)?true:false;
}
bool operator == (const const_iterator& orig)
{
return !(*this != orig);
}
const_iterator(Node* orig)
{
current = orig;
}
const Object& operator*()const      //called by const object
{
return current->mb;
}
const const_iterator& operator++()
{
current = current->next;
return *this;
}
const_iterator operator++(int)
{
const_iterator temp(current);
++(*this);                      //note
return temp;
}
protected:
Node *current;
};
class iterator:public const_iterator
{
public:
iterator(Node *orig):const_iterator(orig){}
const Object& operator*()const      //called by const object
{
return const_iterator::current->mb;
}
Object& operator*()           //called by object
{
return const_iterator::current->mb;
}
};
List();
List(const List& orig);
const List& operator=(const List& orig);
~List();
bool empty();
int size();
const_iterator begin()
{
const_iterator temp(head->next);
return temp;
}
const_iterator end()
{
return const_iterator(tail);
}
void push_back(const Object& orig);
//iterator
private:
Node* head;
Node* tail;
//Node* theList;
int theSize;
};
template<class Object>
List<Object>::List()
{
head = new Node;
tail = new Node;
head->next = tail;
tail->prev = head;
theSize = 0;
}
template<class Object>
List<Object>::List(const List<Object>& orig)
{
Node* tail = new Node;
Node* head = new Node;
Node* temp = head;
for(int i = 0;i < orig.theSize;i++)
{
temp->next = new Node;
temp->next = orig.tail->next;
temp->next->prev = temp;
temp->next->next = tail->prev;
temp = temp->next;
}
theSize = orig.theSize;
}
template<class Object>
const List<Object>& List<Object>::operator = (const List<Object>& orig)
{
if(head != orig.head)           //not the same list
{
Node* temp = head->next;
for(int i = 0;i < theSize;i++)
{
temp = temp->next;
delete temp->prev;
temp->prev = head;
}
temp = head;
for(int i = 0;i < orig.theSize;i++)
{
temp->next = new Node;
temp->next = orig.tail->next;
temp->next->prev = temp;
temp->next->next = tail->prev;
temp = temp->next;
}
theSize = orig.theSize;
}
return *this;
}
template<class Object>
List<Object>::~List()
{
Node* temp = head->next;
for(int i = 0;i < theSize;i++)
{
temp = temp->next;
delete temp->prev;
temp->prev = head;
}
delete head;
delete tail;
}
template<class Object>
bool List<Object>::empty()
{
return (theSize == 0)?true:false;
}
template<class Object>
int List<Object>::size()
{
return theSize;
}
template<class Object>
void List<Object>::push_back(const Object& orig)
{
Node* temp = new Node;
temp->mb = orig;
temp->next = tail;
temp->prev = tail->prev;
tail->prev->next = temp;
tail->prev = temp;
theSize++;
}


template<class Object>
class BinarySearchTree
{
public:
BinarySearchTree();
BinarySearchTree(const BinarySearchTree& orig);
const BinarySearchTree& operator = (const BinarySearchTree& orig);
const Object& findMin()const;
const Object& findMax()const;
bool contains(const Object& x)const;
bool isEmpty()const;
void printTree()const;

void makeEmpty();
void insert(const Object& x);
void remove(const Object& x);
private:
struct BinaryNode
{
Object element;
BinaryNode* left;
BinaryNode* right;
BinaryNode(const Object& orig,BinaryNode* l,BinaryNode* r):
element(orig),left(l),right(r){}
};
BinaryNode* root;
void insert(const Object& x,BinaryNode* &t)const;
void remove(const Object& x,BinaryNode* &t)const;
BinaryNode* findMin(BinaryNode* t)const;
BinaryNode* findMax(BinaryNode* t)const;
bool contains(const Object& x,BinaryNode* t)const;
void makeEmpty(BinaryNode* &t);
void printTree(BinaryNode* t)const;
BinaryNode* clone(BinaryNode* t);
};
template<class Object>
BinarySearchTree<Object>::BinarySearchTree()
{
root = NULL;
}
template<class Object>
BinarySearchTree<Object>::BinarySearchTree(const BinarySearchTree<Object>& orig)
{
root = clone(orig.root);
}
template<class Object>
const BinarySearchTree<Object>& BinarySearchTree<Object>::operator = (const BinarySearchTree<Object>& orig)
{
if(this != &orig)
{
makeEmpty();
root = clone(orig.root);
}
return *this;
}
template<class Object>
bool BinarySearchTree<Object>::contains(const Object& orig)const
{
return contains(orig,root);
}
template<class Object>
bool BinarySearchTree<Object>::contains(const Object& orig,typename BinarySearchTree<Object>::BinaryNode* t)const
{
if(NULL == t)
return false;
else if(orig < t->element)
return contains(orig,t->left);
else if(t->element < orig)
return contains(orig,t->right);
else
return true;
}
template<class Object>
const Object& BinarySearchTree<Object>::findMin()const
{
return findMin(root)->element;
}
template<class Object>
typename BinarySearchTree<Object>::BinaryNode* BinarySearchTree<Object>::findMin(BinaryNode* t )const
{
if(t == NULL)
return t;
if(t->left == NULL)
return t;
else
return findMin(t->left);
}
template<class Object>
const Object& BinarySearchTree<Object>::findMax()const
{
return findMax(root)->element;
}
template<class Object>
typename BinarySearchTree<Object>::BinaryNode* BinarySearchTree<Object>::findMax(BinaryNode* t )const
{
if(t == NULL)
return t;
if(t->right == NULL)
return t;
else
return findMax(t->right);
}
template<class Object>
void BinarySearchTree<Object>::insert(const Object& x)
{
return insert(x,root);
}
template<class Object>
void BinarySearchTree<Object>::insert(const Object& x,BinaryNode* &t)const
{
if(t == NULL)
t = new BinaryNode(x,NULL,NULL);
else if(x < t->element)
insert(x,t->left);
else if(t->element < x)
insert(x,t->right);
else
return;
}
template<class Object>
void BinarySearchTree<Object>::remove(const Object& x)
{
return remove(x,root);
}
template<class Object>
void BinarySearchTree<Object>::remove(const Object& x,typename BinarySearchTree<Object>::BinaryNode* &t)const
{
if(t == NULL)
return ;
else if(x < t->element)
return remove(x,t->left);
else if(t->element < x)
return remove(x,t->right);
else if(t->left != NULL && t->right != NULL)        //two children
{
t->element = findMin(t->right)->element;
remove(t->element,t->right);
}
else
{
BinaryNode* oldNode = t;
t = (t->left != NULL)?t->left:t->right;
delete oldNode;
}
}
template<class Object>
void BinarySearchTree<Object>::makeEmpty()
{
makeEmpty(root);
}
template<class Object>
void BinarySearchTree<Object>::makeEmpty(typename BinarySearchTree<Object>::BinaryNode* &t)
{
if(t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
}
template<class Object>
typename BinarySearchTree<Object>::BinaryNode* BinarySearchTree<Object>::clone(typename BinarySearchTree<Object>::BinaryNode* t)
{
if(t == NULL)
return NULL;
else
return new BinaryNode(t->element,clone(t->left),clone(t->right));
}
template<class Object>
void BinarySearchTree<Object>::printTree()const
{
printTree(root);
}
template<class Object>
void BinarySearchTree<Object>::printTree(typename BinarySearchTree<Object>::BinaryNode* t)const
{
if(t != NULL)
{
cout << t->element << endl;
printTree(t->left);
printTree(t->right);
}
}


//考虑问题:散列函数,装填因子 (表中元素的个数与表大小的比值)
//再散列:装填因子大于1的时候考虑再散列,一般是将表的大小扩充一倍后的第一个素数
template<class Object>
class HashTable
{
public:
explicit HashTable(int size = 101);
bool contains(const Object& orig)const;
void makeEmpty();
void insert(const Object& orig);
bool remove(const Object& orig);
private:
vector< list<Object> > theLists;
int currentSize;// the num of elements
int myHash(const Object& orig)const;
};
template<class Object>
int HashTable<Object>::myHash(const Object& orig)const
{
int hashValue = hash(orig);
hashValue %= theLists.size();
if(hashValue < 0)
hashValue += theLists.size();
return hashValue;
}
template<class Object>
bool HashTable<Object>::contains(const Object& orig)const
{
int hashValue = myHash(orig);
typename typedef list<Object>::iterator iterator;
iterator beg = theLists[hashValue].begin();
iterator end = theLists[hashValue].end();
return find(beg,end,orig) != end;
}
template<class Object>
void HashTable<Object>::makeEmpty()
{
for(int i = 0;i < theLists.size();i++)
theLists[i].clear();				//并没有释放内存
}
template<class Object>
void HashTable<Object>::insert(const Object& orig)
{
int hashValue = myHash(orig);
const list<Object>& whichList = theLists[hashValue];
if(find(whichList.begin(),whichList.end(),orig) == whichList.end())//元素不在链表中
whichList.push_back(orig);
}
template<class Object>
bool HashTable<Object>::remove(const Object& orig)
{
const list<Object>& whichList = theLists[hash(orig)];
typename list<Object>::const_iterator iter = find(whichList.begin(),whichList.end(),orig);
if(iter != whichList.end())
{
whichList.erase(iter);
--current
return true;
}
return false;
}
//string hash function
int hash(const string& orig)
{
int value(0);
for(size_t i = 0;i < orig.size();i++)
value += orig[i];
return value;
}
enum Status
{EMPTY,ACTIVE,DELETED};
template<class Object>
struct Node
{
Object element;
Status elementStatus;
};


//用数组来实现
//不需要使用链
//二插堆:堆序性质
//对于每个节点X,X的父亲中的键小于(或等于)X中得键,根结点除外(它没有父亲)
//insert采用上滤策略 指的是空穴
//remove采用下滤策略
template<class Object>
class BinaryHeap
{
public:
explicit BinaryHeap(int size = 101);
explicit BinaryHeap(const vector<Object>& orig);
void insert(const Object& orig);
void deleteMin();
void deleteMin(const Object& orig);
bool isEmpty()const;
void makeEmpty();
void print()const;

private:
void buildHeap();
void percolatedown(int hole);
vector<Object> theArray;	//the heap array
int theSize;	//the number of elements
};
//向上过滤
template<class Object>
void BinaryHeap<Object>::insert(const Object& orig)
{
if(theSize == theArray.size()-1)
theArray.resize(theSize*2);
int hole = ++theSize;	//元素当前本应该插入的位置
for(;hole > 1 && orig < theArray[hole/2];hole /= 2)	//不断的与父结点进行比较一直找到比它小得父亲结点
theArray[hole] = theArray[hole/2];
theArray[hole] = orig;
}
//向下过滤
template<class Object>
void BinaryHeap<Object>::deleteMin()
{
Object temp = theArray[theSize--];	//保存一个基准元素用来进行比较
int hole = 1;
//把剩下元素中最小的元素顶上去
int child;	//儿子结点的索引
for(;hole * 2 <= theSize;hole = child)
{
child = hole * 2;
if(child != theSize && theArray[child+1] < theArray[child])	//
child++;
if(theArray[child] < temp)
theArray[hole] = theArray[child];	//将儿子结点的元素向上推
else
break;
}
theArray[hole] = temp;	//将基准元素填入最后找到的结点位置
}
template<class Object>
BinaryHeap<Object>::BinaryHeap(int size):theArray(size),theSize(0)
{

}
template<class Object>
void BinaryHeap<Object>::makeEmpty()
{
theSize = 0;
theArray.clear();
}
template<class Object>
void BinaryHeap<Object>::print()const
{
for(int i = 0;i < theSize;i++)
cout << theArray[i+1] << " ";
}
template<class Object>
BinaryHeap<Object>::BinaryHeap(const vector<Object>& orig):theArray(orig.size() + 10),
theSize(orig.size())
{
for(size_t i = 0;i < orig.size();i++)
theArray[i+1] = orig[i];
buildHeap();
}
template<class Object>
void BinaryHeap<Object>::buildHeap()
{
for(size_t i = theSize/2;i > 0;i--)
percolatedown(i);
}
template<class Object>
void BinaryHeap<Object>::percolatedown(int hole)
{
int child;	//儿子结点的索引
for(;hole * 2 <= theSize;hole = child)	//退出条件是没有儿子结点,这时hole*2 > theSize
{
child = hole * 2;
if(child != theSize && theArray[child+1] < theArray[child])	//找出儿子结点中的较小项
child++;
if(theArray[child] < temp)
theArray[hole] = theArray[child];	//将儿子结点的元素向上推
else
break;
}
theArray[hole] = temp;	//将基准元素填入最后找到的结点位置
}


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

//插入排序 将P位置的元素插到前P+1个元素中的正确位置,保证在P位置的时候前面的
//的元素是处于排序状态
//时间复杂度O(N*N)的时间界
template<class Comparable>
void insertionSort(vector<Comparable>& a)
{
int j;
for(size_t p = 1;p < a.size();p++)
{
Comparable temp = a[p];
for(j = p;j > 0 && temp < a[j-1];j--)
a[j] = a[j-1];
a[j] = temp;
}
}
template<class Comparable>
void insertionSort(vector<Comparable>& a,int left,int right)
{
int j;
for(size_t p = left + 1;p <= right;p++)
{
Comparable temp = a[p];
for(j = p;j > 0 && temp < a[j-1];j--)
a[j] = a[j-1];
a[j] = temp;
}
}
//shell排序 保证h(k)排序性
//缩减增量排序
template<class Comparable>
void shellsort(vector<Comparable>& a)
{
for(int gap = a.size()/2;gap > 0;gap /= 2)
{
for(size_t i = gap;i < a.size();i++)
{
Comparable temp = a[i];
int j = i;
for(;j >= gap && temp < a[j-gap];j -= gap)
a[j] = a[j-gap];
a[j] = temp;
}
}
}
//堆排序
//利用二叉堆的堆序性质
inline int leftchild(int i)
{
return i * 2 + 1;
}
template<class Comparable>
void percolatedown(vector<Comparable>& a,int i,int n)	//数组,下滤的空穴位置,边界范围
{
int child;
Comparable temp;
for(temp = a[i];leftchild(i) < n;i = child)
{
child = leftchild(i);						//
if(child != n - 1 && a[child] < a[child + 1])
child++;
if(temp < a[child])
a[i] = a[child];
else
break;
}
a[i] = temp;
}
template<class Comparable>
void heapsort(vector<Comparable>& a)
{
for(int i = a.size()/2;i >= 0;i--)
percolatedown(a,i,a.size());
for(int j = a.size()-1;j > 0;j--)
{
swap(a[0],a[j]);
percolatedown(a,0,j);
}
}
//归并排序 采用分治策略
template<class Comparable>
void merge(vector<Comparable>& a,vector<Comparable>& tempArray,int leftpos,
int rightpos,int rightend)		//归并函数,将两个排好序的数据合并
{
int leftend = rightpos - 1;
int temppos = leftpos;
int numelements = rightend - leftend + 1;
//
while(leftpos <= leftend && rightpos <= rightend)
if(a[leftpos] <= a[rightpos])
tempArray[temppos++] = a[leftpos++];
else
tempArray[temppos++] = a[rightpos++];
while(leftpos <= leftend)
tempArray[temppos++] = a[leftpos++];
while(rightpos <= rightend)
tempArray[temppos++] = a[rightpos++];
for(int i = 0;i < numelements;i++,rightend--)
a[rightend] = tempArray[rightend];
}
template<class Comparable>
void mergesort(vector<Comparable>& a,vector<Comparable>& tempArray,
int left,int right)	//分治函数 运用递归思想进行分治
{
if(left < right)
{
int center = (left + right) / 2;
mergesort(a,tempArray,left,center);
mergesort(a,tempArray,center + 1,right);
merge(a,tempArray,left,center + 1,right);
}
}
template<class Comparable>
void mergesort(vector<Comparable>& a)
{
vector<Comparable> tempArray(a.size());	//临时数组 用于归并
mergesort(a,tempArray,0,a.size() - 1);
}
//快速排序算法
//三元素中值算法,将最小的放在最左边,最大的放在最后边,枢纽元放在right-1的位置
//并返回枢纽元
template<class Comparable>
const Comparable&  median3(vector<Comparable>& a,int left,int right)
{
int center = (left + right) / 2;
if(a[center] < a[left])
swap(a[center],a[left]);
if(a[right] < a[left])
swap(a[right],a[left]);	//把最小的元素放在a[left]的位置
if(a[right] < a[center])	//把另外两个元素放在相应的位置,最大的在a[right]位置,小的在a[center]的位置
swap(a[center],a[right]);
swap(a[center],a[right - 1]);	//将枢纽元放在right - 1的位置
return a[right - 1];
}
template<class Comparable>
void quicksort(vector<Comparable>& a,int left,int right)	//分割函数
{
if(left + 10 <= right)
{
Comparable pivot = median3(a,left,right);
int i = left,j = right - 1;
for(;;)							//循环将大于枢纽元的元素移到右边,小于枢纽元的移到左边
{
while(a[++i] < pivot){}
while(pivot < a[--j]){}
if(i < j)
swap(a[i],a[j]);
else		//交错之后就不执行循环
break;
}
swap(a[i],a[j-1]);	//交错之后将i位置的元素和枢纽元进行交换
quicksort(a,left,i);		//排序小元素组成的数组
quicksort(a,i + 1,right);	//排序大元素组成的数组
}
else							//当元素的个数不大于10个的时候就采用插入排序算法
insertionSort(a,left,right);
}
template<class Comparable>
void quicksort(vector<Comparable>& a)
{
quicksort(a,0,a.size() - 1);
}

int main()
{
int arr[5] = {44,3,4,53,234};
cout << "insert sort" << endl;
vector<int> ivec(arr,arr+5);
insertionSort(ivec);
for(size_t i = 0;i < ivec.size();i++)
cout << ivec[i] << " ";
cout << endl;
cout << "shell sort" << endl;
vector<int> ivecs(arr,arr+5);
shellsort(ivecs);
for(size_t i = 0;i < ivecs.size();i++)
cout << ivecs[i] << " ";
cout << endl;
cout << "heap sort" << endl;
vector<int> ivech(arr,arr+5);
heapsort(ivech);
for(size_t i = 0;i < ivech.size();i++)
cout << ivech[i] << " ";
cout << endl;
cout << "meger sort" << endl;
vector<int> ivecm(arr,arr+5);
mergesort(ivecm);
for(size_t i = 0;i < ivecm.size();i++)
cout << ivecm[i] << " ";
cout << endl;
cout << "quick sort" << endl;
vector<int> ivecq(arr,arr+5);
mergesort(ivecq);
for(size_t i = 0;i < ivecq.size();i++)
cout << ivecq[i] << " ";
return 0;
}


常用的数据结构 数组,链表,队列,栈,二叉树,优先队列,散列

常用的排序算法 插入排序,shell 排序,堆排序,归并排序,快速排序

这些是数据结构的基础,就算一个例子敲上十遍二十遍都是值得的,我们必须达到透彻理解这些基础的程度,不仅会写实现,更要明白设计思想,针对问题能够快速应对组合出更复杂的数据结构。

这些是基础,是进一步学习数据结构和算法的前提,最终我们要学习的是设计算法的思想,如果没有这些基础是不可能继续深入学习的,所以在这些上面花费半年或者更长得时间是值得的。

2012.03.22 qs
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: