关闭

常用数据结构和算法基础

标签: 数据结构算法iteratorobjectinsertnull
733人阅读 评论(0) 收藏 举报
分类:
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

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:35276次
    • 积分:683
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    最新评论