排序算法
待排序数组如下,只需要把Sort函数更换即可。
int main()
{
const int N = 8;
int A[N] = { 1,0,5,4,4,9,8,10};
Sort(A, N);
for (int i = 0; i < N; i++)
{
std::cout << A[i] << " ";
}
return 0;
}
- 插入排序
伪码描述
for j=1 to A.length
key=A[j];
i=j;
while i>0 && A[i-1]>key
A[i]=A[i-1];
i--;
A[i]=key;
**代码**
/*插入排序*/
void InsertSort(ElementType A[], int N)
{
int i, j;
int key;
for (j = 1; j < N; j++)
{
key = A[j];
i = j;
while (i > 0 && A[i-1]>key)
{
A[i] = A[i-1];
i -= 1;
}
A[i] = key;
}
}
运行结果
2. 归并排序
归并排序的核心思想是分而治之。直观上操作如下
分解:将待排序的n个元素的序列分成两个有n/2个元素的序列;
解决:使用归并排序递归地排序两个子序列,当子序列长度为1时返回;
合并:合并两个已排序的子序列得到最终的排序好的序列。
其中合并的思想为每次从两个已经排序的子序列中取出较小的元素放入最终的数组中。代码如下描述如下:
/*归并排序*/
void MSort(ElementType A[], int N)
{
ElementType* TmpA = new ElementType[N]{ 0 };
if (N > 0)
{
MergeSort(A, TmpA, 0, N - 1);
}
}
void MergeSort(ElementType A[],ElementType TmpA[],int L,int RightEnd)
{
int center;
if(L<RightEnd)
{
center = (L + RightEnd) / 2;
MergeSort(A, TmpA, L, center);
MergeSort(A, TmpA, center + 1, RightEnd);
Merge(A, TmpA, L, center+1, RightEnd);
}
}
void Merge(ElementType A[], ElementType TmpA[],int L, int R, int RightEnd) //归并
{
int i;
int left = L, right = R, Tmp = L;
int LeftEnd = R - 1;
while (left <= LeftEnd && right <= RightEnd)
{
if (A[left] <= A[right])
{
TmpA[Tmp++] = A[left++];
}
else
{
TmpA[Tmp++] = A[right++];
}
}
while (left < R)
{
TmpA[Tmp++] = A[left++];
}
while (right < RightEnd+1)
{
TmpA[Tmp++] = A[right++];
}
for (left=L;left<=RightEnd;left++)
{
A[left] = TmpA[left];
}
}
int main()
{
const int N = 8;
int A[N] = { 1,0,5,4,4,9,8,10};
MSort(A, N);
for (int i = 0; i < N; i++)
{
std::cout << A[i] << " ";
}
return 0;
}
3.希尔排序
希尔排序定义增量序列,每次对相应增量间隔的数进行插入排序。增量序列的值为1时,完成排序。
/*希尔排序*/
void ShellSort(ElementType A[], int N)
{
int D; //增量序列
int i, j;
int tmp;
ElementType* TmpA = new ElementType[N];
for (D = N / 2; D > 0; D /= 2)
{
for (i = D; i < N; i++)
{
tmp = A[i];
j = i;
while (j>=D&&A[j-D]>tmp)
{
A[j] = A[j-D];
j -= D;
}
A[j] = tmp;
}
}
}
4.堆排序
算法思想:
从最后一个叶子结点的父结点开始,调整元素的位置,使其满足最大堆的性质,到达跟结点时,完成建堆过程;
交换跟结点元素和最后一个元素的位置,并且堆元素的数目减一,调整跟结点元素的位置,使其满足最大堆的性质,当堆元素数目为0时,完成排序。
代码如下:
void HeapSort(ElementType A[], int N)
{
int i;
ElementType tmp;
for (i = N/2-1; i >= 0; i--) /*建堆*/
{
PercDown(A, i, N);
}
for (i = N-1; i > 0; i--)
{
tmp = A[i]; /*Swap,即DeleteMax*/
A[i] = A[0];
A[0] = tmp;
PercDown(A, 0, i);
}
}
void PercDown(ElementType A[],int i,int N)
{
int parent, child;
int tmp;
for (parent = i; parent*2+1 < N; parent=child)
{
tmp = A[parent];
child = parent * 2+1;
if ((child != N - 1) && (A[child] < A[child + 1]))
child++;
if (tmp > A[child]) break;
else
{
A[parent] = A[child];
A[child] = tmp;
}
}
}
5.随机化的快速排序
算法思想:每次排序将随机选取一个待排序数组中的元素值x作为分割,RandomPartiton函数处理后,前半部分为小于等于x的元素,后半部分为大于x的元素,递归调用,就可以完成整个序列的排序。
代码如下:
/*随机化的快速排序*/
/*统一接口*/
void QuickSort(ElementType A[], int N)
{
if (N > 0)
{
QSort(A, 0, N - 1);
}
}
void QSort(ElementType A[], int p, int r)
{
int q;
if (p < r)
{
q = RandomPartiton(A, p, r);
QSort(A, p, q - 1);
QSort(A, q + 1, r);
}
}
int RandomPartiton(ElementType A[], int p, int r)
{
int random = (rand() % (r - p + 1)) + p;
//交换A[random]和A[r]
int tmp=A[random];
A[random] = A[r];
A[r] = tmp;
int x = A[r];
int i,j,k;
i = p - 1;
for (j = p; j < r; j++)
{
if (A[j] <= x)
{
i = i + 1;
tmp = A[i]; /*Swap A[j]和A[i+1]*/
A[i] = A[j];
A[j] = tmp;
}
}
/*交换A[r]与A[i+1]*/
tmp = A[r];
A[r] = A[i + 1];
A[i + 1] = tmp;
return i + 1;
}