内排序算法基本上分为:选择排序,插入排序,交换排序,归并排序
1.选择排序
1.1基本选择排序
算法思想:每i趟通过n - i次关键码比较,在n-i + 1(1<=i<=n-1)个记录中选取关键码最小的记录,并和第i个记录进行交换,成为有序序列
//***********************************************************************************
//* Function: 交换函数
//* Parameter: (I/O) T& a : 源交换元素
//* (I/O) T& b : 目的交换元素
//***********************************************************************************
template <typename T>
void Swap(T& a,T& b)
{
T tmp = a;
a = b;
b = tmp;
};
//***********************************************************************************
//* Function: 简单选择排序
//* Parameter: (I/O) T A[] : 待排序的数组
//* (I) int n : 数组元素个数
//***********************************************************************************
template <typename T>
void SelectSort(T A[], int n)
{
int iMin = 0;
for (int i = 0; i < n; i++)
{
iMin = i; // 默认A[i]为第i小
for (int j = i+1; j < n; j++)
{
if (A[iMin] > A[j])
{
iMin = j; // 记录第j个为A[i]
}
}
Swap(A[i], A[iMin]);
}
}
1.2直接插入排序
算法思想:把待排序序列中的记录一个一个地插入到一个有序序列里,比如:{3、2、1},把3拿出来放入A中,把2拿出来和A中最左边的记录开始比较,大就放在A的最左边,小的话,3往后挪一位,然后再拿和2和3前面的记录进行比较,直到该记录不大于2或者没有记录了,2就插到这一位,这一趟的排序完成//***********************************************************************************
//* Function: 直接插入排序
//* Parameter: (I/O) T A[] : 待排序的数组
//* (I) int n : 数组元素个数
//***********************************************************************************
template <typename T>
void InsertSort(T A[], int n)
{
for (int i = 1; i < n; i++)
{
T temp=A[i];
int j = 0;
for (j = i; (j > 0) && (temp < A[j-1]); j--) // 从后到前与Temp比较,得到插入位置
{
A[j] = A[j-1]; // 此时该位置已经被i - 1占据
}
// 得到需要给当前的A[j]的赋值
A[j] = temp;
}
}
1.3冒泡排序
算法思想:临近的两个记录进行比较,第j-1个记录大于j时,这两个记录进行交换,直到得出本趟最大的
//***********************************************************************************
//* Function: 冒泡排序(最简单的交换排序)
//* Parameter: (I/O) T A[] : 待排序的数组
//* (I) int n : 数组元素个数
//***********************************************************************************
template <class T>
void BubbleSort(T A[], int n)
{
for (int i = 0; i < n; i++) // 本趟从第1个元素开始冒泡
{
for (int j = 1; j < n - i; j++) // 本趟找出最大的元素放
{
if (A[j] < A[j-1])
{
Swap(A[j], A[j-1]);
}
}
}
}
1.4快速排序
算法思想:在待排序列中以其中一个记录为轴值,把这个序列中所有大于轴值的记录放在右边,小于轴值的放在左边,这样分成两个区间,然后再对这两个区间序列进行相同的处理,一次区分过程结束,排序过程可递归进行,若排序序列中只有一个记录,则结束递归。
//***********************************************************************************
//* Function: 快速排序
//* Parameter: (I/O) T A[] : 待排序的分区
//* (I) int left : 分区左边的位置
//* (I) int right : 分区右边的位置
//***********************************************************************************
template <typename T>
int Partition(T A[], int left, int right)
{
int i = left, j = right; // 以left为轴值,即此时的A[i]
while (i < j)
{
while (i< j && A[i] <= A[j]) j--; // 从右边开始查找比轴值小的,找到后交换
if (i < j)
{
Swap(A[i], A[j]);
i++; // 此步可以省下一次比较
}
while (i< j && A[i] <= A[j]) i++; // 然后再从左边开始查找比轴值大的,找到后交换
if (i < j)
{
Swap(A[i], A[j]);
j--; // 此步可以省下一次比较
}
}
return i;
}
//***********************************************************************************
//* Function: 快速排序
//* Parameter: (I/O) T A[] : 待排序的数组
//* (I) int n : 数组元素个数
//***********************************************************************************
template <typename T>
void QuickSort(T A[], int left, int right)
{
if (left < right)
{
int pivot = Partition(A, left, right);
QuickSort(A, left,pivot -1);
QuickSort(A, pivot+1, right);
}
}