常用數據結構與算法之排序算法


排序算法

/*
 * =====================================================================================
 *
 *       Filename:  sort.h
 *
 *    Description:  template func of rand & sort alg
 *
 *        Version:  1.0
 *        Created:  2012年03月08日 15時36分00秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Lavey Luo (lavey), [email protected]
 *   Organization:  
 *
 * =====================================================================================
 */

#ifndef  __SORT_H__
#define __SORT_H__
namespace stcpp
{
	template<class T>
		/* Rand the n elements a[0..n-1]  */
		/* elements ranks returned in r[0..n-1] */
		void Rank(T a[], int n, int r[])
		{
			for (int i = 0; i < n; i++)
				r[i] = 0;
			/*  the flow loop has the same result */
#if 0
			for (int i = 0; i < n; i++)
				for (int j = i+1; j < n; j++)
					if (a[i] > a[j])
						r[i] += 1;
					else
						r[j] += 1;
#else
			for (int i = 1; i < n; i++)
				for (int j = 0; j < i; j++)
					if (a[i] >= a[j])
						r[i] += 1;
					else
						r[j] += 1;

#endif
		}

	/* 根據數組a的元素排序位置r,將其按大小重派 */
	template<class T>
		/* In-place rearrangement into sorted order */
		void Rearrange(T a[], const int n, int r[])
		{
			T tmp[n];

			// move the correct place in tmp
			for (int i = 0; i < n; i++)
				tmp[r[i]] = a[i];
			
			// replace by the sorted array
			for (int i = 0; i < n; i++)
				a[i] = tmp[i];
		}

	/* 選擇排序。從小到大排,每次選擇剩下元素中最小的放到對應位置 */
	template<class T>
		void SelectionSort(T a[], int n)
		{
			 for (int i = 0; i < n; i++)
			 {
				 // find the min 
				 int k = i;
				 for (int j = i + 1; j < n; j++ )
				 {
						if (a[k] > a[j])	
							k = j;
				 }

				 //swap a[i] with a[k] 
				 if (k != i) 
				 {
					 T b  = a[i]; a[i] = a[k]; a[k] = b;
				 }
			 }
		}

	/* 冒泡排序,相鄰的兩兩相比,大的放右邊 */
	template<class T>
		void BubbleSort(T a[], int n)
	{
		for (int i = 0; i < n; i++)
			for (int j = 1; j < n - i; j++ )
				if (a[j-1] > a[j])
				{
					 T b  = a[j-1]; a[j-1] = a[j]; a[j] = b;
				}
	}


	/* 冒泡排序,優化對已排好的序的跳過*/
	template<class T>
		void BubbleSort_q(T a[], int n)
	{
		bool sorted = false;
		for (int i = 0; i < n && !sorted; i++)
		{
			sorted = false;
			for (int j = n - 1; j > i; j-- )
			{
				if (a[j-1] > a[j])
				{
					 T b  = a[j-1]; a[j-1] = a[j]; a[j] = b;
					 sorted = true;
				}
			}
		}
	}

	/* 插入排序 */
	template<class T>
		void InsertionSort(T a[], int n)
		{
			for (int i = 1; i < n; i++)               /* 從位置1開始 */
			{
				T e = a[i];                             /* 記住哨兵 */
				Insert(a, i, e);
			}
		}
	template<class T>
		void Insert(T a[], int n, const T& e)       /* 在有序的數組a[0, n-1]中插入元素e */
		{
			int i = n - 1;
			for (; i >= 0 && a[i] > e; i--)
				a[i+1] = a[i];
			a[i+1]  = e;
		}


	/* 插入排序2,  合併插入過程 */

	template<class T>
		void InsertionSort2(T a[], int n)
		{
			for (int i = 1; i < n; i++)
			{
				int j = i - 1;
				T e = a[i];                             /* 記住要插入的元素值,不能直接引用a[i] */
				// 插入元素到合適的位置					
				for (; j >= 0 && a[j] > e; j--)
					a[j+1] = a[j];
				a[j+1]  = e;
			}
		}

	/* 希爾排序 */
	template<class T>
		void ShellSort(T a[],  int n)
		{
			int i, j;
			int increment = n;
			do
			{
				increment =  increment/3 +1;/* 增量序列 */
				for ( i = increment; i < n; i++)
				{
					 if (a[i] < a[i-increment])
					 {
							T e = a[i];
							j = i - increment;

							do                                /* 查找e的插入位置*/
							{
								a[j+increment] = a[j];          /*  記錄後移,查找插入位置 */
								j = j - increment;
							} while (j>0 && e < a[j]);
							a[j+increment] = e;                /*  插入 */
					 }
				}
			} while (increment>1);
		}
	/* 歸併排序 */
	template<class T>
		/* 將有序的a[begin...mind] 和 a[mind+1...end] 歸併爲有序的b[begin...end]*/
		void Merge(T a[], T b[], int begin,  int mind , int end)
		{
			 int begin1 = begin;
			 int end1	  = mind;
			 int begin2 = mind+1;
			 int end2   = end;
			 int k      = begin;

			 while (begin1 <= end1 && begin2 <= end2) /* 將a[]中的元素從小到大歸併到b[] */
			 {
					if (a[begin1] < a[begin2])
						b[k++] = a[begin1++];
					else
						b[k++] = a[begin2++];
			 }

			 /* 將剩餘的a[begin1...end1]複製到b[] */
			 if (begin1 <= end1)
			 {
				 while (begin1 <= end1)
					 b[k++] = a[begin1++];
			 }
			 /* 將剩餘的a[begin2...end2]複製到b[] */
			 if (begin2 <= end2)
			 {
				 while (begin2 <= end2)
					 b[k++] = a[begin2++];
			 }
		}

	/* 遞歸歸併排序 */
	template<class T>
		/* =將a[s..t]歸併排序爲b[s..t] */
		void MSort(T a[], T b[], int s,  int t)
		{
			int m =  (s+t)/2;
			T TMP[100]; //最大的臨時空間
			if (s == t)
				b[s] = a[s];
			else
			{
				MSort(a, TMP, s, m);
				MSort(a, TMP, m+1, t);
				Merge(TMP, b, s, m, t);
			}
		}

	template<class T>
		void MergSort1(T a[], int len)
		{
			MSort(a, a, 0, len -1);
		}

	/* 非遞歸歸併排序 */
	template<class T>
		/* 將a[]中相鄰長度爲seg的字串兩兩歸併到b[], a的長度爲size */
		void MergePass(T a[], T b[], int seg, int size)
		{
			int start_seg = 0;
			while (start_seg < size - 2*seg) //滿足兩兩歸併的最少長度
			{
				Merge(a, b, start_seg, start_seg + seg -1,  start_seg + 2*seg -1);
				start_seg += 2*seg;
			}

			if (start_seg + seg < size)                 /* 還剩餘大於seg長度的序列 */
			{
				Merge(a, b, start_seg, start_seg + seg -1, size -1);
			}
			else
			{
				while (start_seg < size)
				{
					b[start_seg] = a[start_seg];
					start_seg++;
				}
			}
		}
	
	template<class T>
		void MergeSort2(T a[],  int len)
		{
				T* tmp =  new T[len];
				int seg = 1;
				while (seg < len)
				{
					MergePass(a, tmp, seg, len);
					seg *= 2;
					MergePass(tmp, a, seg, len);
					seg *= 2;
				}
		}

	/* 堆排序 */
	template<class T>
		void HeapAdjust(T a[],  int s, int m)
		{
			 int temp = a[s];
			 for (int j = 2*s; j<=m; j*=2) // j 爲s的子節點
			 {
				 if (j < m && a[j] < a[j+1])
					 ++j; // 指向右子節點
				
				  if (temp >= a[j])
						break;
					a[s] = a[j];
					s = j;
			 }
			 a[s] = temp; // 插入
		}
	template<class T>
		void HeapSort(T a[], int len)
		{
			/* 構建一個大頂堆 */
			for (int i = len/2 - 1;  i>= 0; i--)
				HeapAdjust(a, i, len);

			for(int i = len -1; i>0; i--)
			{
				T t  = a[0];
				a[0] = a[i];
				a[i] =  t;
				HeapAdjust(a, 0, i-1);
			}
		}

	/* 快速排序 */
	template<class T>
		int Partition(T a[],  int low, int high)
		{
			int pivotkey = a[low];
			while (low < high)
			{
				 while (low < high && a[high] >= pivotkey)
					 high--;

				 // swap a[low] with a[high]
				 T t = a[low];
				 a[low] = a[high];
				 a[high] = t;

				 while (low < high && a[low] <= pivotkey)
					 low++;

				 t = a[low];
				 a[low] = a[high];
				 a[high] = t;
			}
			return low;
		}

	template<class T>
		void QSort(T a[],  int low, int high)
		{
			int pivot;
			if (low < high)
			{
				 pivot = Partition(a, low, high);
				 QSort(a,  low, pivot -1);
				 QSort(a,  pivot + 1, high);
			}
		}
	template<class T>
		void QuickSort(T a[],  int len)
		{
			QSort(a, 0, len -1);
		}
}
#endif  //__SORT_H__


測試用列:

/*
 * =====================================================================================
 *
 *       Filename:  test_sort.cpp
 *
 *    Description:  test_sort
 *
 *        Version:  1.0
 *        Created:  2012年03月08日 16時22分40秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Lavey Luo (lavey), [email protected]
 *   Organization:  
 *
 * =====================================================================================
 */
#include "sort.h"
#include <iostream>
using std::cout;
using std::endl;

int test_sort(int argc,  char** argv)
{
	 int a[]  = {2, 6, 4, 3, 1, 5};
	 const unsigned int len  = sizeof(a)/sizeof(int);
	 int r[len] = {0};

	 cout <<  "a: "; 
	 for (unsigned int i = 0; i < len; i++)
		 cout << a[i] << " ";
	 cout << endl;
	 stcpp::Rank(a, len, r);
	 cout <<  "r: "; 
	 for (unsigned int i = 0; i < len; i++)
		 cout << r[i] << " ";
	 cout << endl;

	 cout << endl << "Rearrange::" << endl;
	 stcpp::Rearrange(a, len, r);
	 cout <<  "sorted a: "; 
	 for (unsigned int i = 0; i < len; i++)
		 cout << a[i] << " ";
	 cout << endl;

	 cout << endl << "SelectionSort::" << endl;
	 int b[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "b: "; 
	 for (unsigned int i = 0; i <  sizeof(b)/sizeof(int); i++)
		 cout << b[i] << " ";
	 cout << endl;
	 stcpp::SelectionSort(b, sizeof(b)/sizeof(int));
	 cout <<  "sorted b: "; 
	 for (unsigned int i = 0; i <  sizeof(b)/sizeof(int); i++)
		 cout << b[i] << " ";
	 cout << endl;

	 cout << endl << "BubbleSort::" << endl;
	 int c[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "c: "; 
	 for (unsigned int i = 0; i <  sizeof(c)/sizeof(int); i++)
		 cout << c[i] << " ";
	 cout << endl;
	 stcpp::BubbleSort(c, sizeof(c)/sizeof(int));
	 cout <<  "sorted c: "; 
	 for (unsigned int i = 0; i <  sizeof(c)/sizeof(int); i++)
		 cout << c[i] << " ";
	 cout << endl;
	 

	 cout << endl << "InsertSort::" << endl;
	 int d[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "d: "; 
	 for (unsigned int i = 0; i <  sizeof(d)/sizeof(int); i++)
		 cout << d[i] << " ";
	 cout << endl;
	 stcpp::InsertionSort(d, sizeof(d)/sizeof(int));
	 cout <<  "sorted d: "; 
	 for (unsigned int i = 0; i <  sizeof(d)/sizeof(int); i++)
		 cout << d[i] << " ";
	 cout << endl;

	 cout << endl << "InsertSort2::" << endl;
	 int e[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "e: "; 
	 for (unsigned int i = 0; i <  sizeof(e)/sizeof(int); i++)
		 cout << e[i] << " ";
	 cout << endl;
	 stcpp::InsertionSort2(e, sizeof(e)/sizeof(int));
	 cout <<  "sorted e: "; 
	 for (unsigned int i = 0; i <  sizeof(e)/sizeof(int); i++)
		 cout << e[i] << " ";
	 cout << endl;


	 cout << endl << "Shell sort::" << endl;
	 int f[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "f: "; 
	 for (unsigned int i = 0; i <  sizeof(f)/sizeof(int); i++)
		 cout << f[i] << " ";
	 cout << endl;
	 stcpp::ShellSort(f, sizeof(f)/sizeof(int));
	 cout <<  "sorted f: "; 
	 for (unsigned int i = 0; i <  sizeof(f)/sizeof(int); i++)
		 cout << f[i] << " ";
	 cout << endl;


	 cout << endl << "merge sort 1::" << endl;
	 int g[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "g: "; 
	 for (unsigned int i = 0; i <  sizeof(g)/sizeof(int); i++)
		 cout << g[i] << " ";
	 cout << endl;
	 stcpp::MergSort1(g, sizeof(g)/sizeof(int));
	 cout <<  "sorted g: "; 
	 for (unsigned int i = 0; i <  sizeof(g)/sizeof(int); i++)
		 cout << g[i] << " ";
	 cout << endl;

	 cout << endl << "merge sort 2::" << endl;
	 int h[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "h: "; 
	 for (unsigned int i = 0; i <  sizeof(h)/sizeof(int); i++)
		 cout << h[i] << " ";
	 cout << endl;
	 stcpp::MergeSort2(h, sizeof(h)/sizeof(int));
	 cout <<  "sorted h: "; 
	 for (unsigned int i = 0; i <  sizeof(h)/sizeof(int); i++)
		 cout << h[i] << " ";
	 cout << endl;


	 cout << endl << "heap sort 2::" << endl;
	 int hh[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "hh: "; 
	 for (unsigned int i = 0; i <  sizeof(hh)/sizeof(int); i++)
		 cout << hh[i] << " ";
	 cout << endl;
	 stcpp::HeapSort(hh, sizeof(hh)/sizeof(int));
	 cout <<  "sorted hh: "; 
	 for (unsigned int i = 0; i <  sizeof(hh)/sizeof(int); i++)
		 cout << hh[i] << " ";
	 cout << endl;


	 cout << endl << "quick sort 2::" << endl;
	 int qq[]  = {2, 6, 4, 3, 1, 5};
	 cout <<  "qq: "; 
	 for (unsigned int i = 0; i <  sizeof(qq)/sizeof(int); i++)
		 cout << qq[i] << " ";
	 cout << endl;
	 stcpp::QuickSort(qq, sizeof(qq)/sizeof(int));
	 cout <<  "sorted qq: "; 
	 for (unsigned int i = 0; i <  sizeof(qq)/sizeof(int); i++)
		 cout << qq[i] << " ";
	 cout << endl;
	 return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章