常用数据结构和算法基础
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
相关文章推荐
- c++基础8:常用的数据结构及算法
- 一步一步复习数据结构和算法基础-顺序查找+二分查找
- Python常用算法学习基础教程
- 算法与数据结构基础系列(一): 链表的常见问题分析及实现
- 数据结构和算法分析之排序篇--归并排序(Merge Sort)和常用排序算法时间复杂度比较(附赠记忆方法)
- 数据结构----图论基础算法的小合集(1)
- 计算机基础算法及数据结构综述
- Redis基础、高级特性与性能调优-Redis的数据结构和相关常用命令
- 数据结构和算法 – 1.基础排序算法
- 常用的数据结构以及算法
- C算法_基础数据结构18/1/30 8大排序
- 算法基础——十种常用排序算法的Java及Python实现
- 常用的算法和数据结构分析(查找和排序)
- 常用算法和数据结构的复杂度介绍
- Java基础数据结构和算法
- 《软件设计师》——数据结构和算法基础
- 计算机常用基础算法
- 一步一步复习数据结构和算法基础-深度优先搜索
- 常用的数据结构以及算法
- 一步一步复习数据结构和算法基础-插入排序(2)