交换排序概念
交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。
应用交换排序基本思想的主要排序方法有:冒泡排序和快速排序。
1.冒泡
1.1 排序思想
依次比较相邻的两个记录的关键字,若两个记录是反序的(即前一个记录的关键字大于后前一个记录的关键字),则进行交换,直到没有反序的记录为止。
①首先将L->R[1]与L->R[2]的关键字进行比较,若为反序(L->R[1]的关键字大于L->R[2]的关键字),则交换两个记录;然后比较L->R[2]与L->R[3]的关键字,依此类推,直到L->R[n-1]与L->R[n]的关键字比较后为止,称为一趟冒泡排序,L->R[n]为关键字最大的记录。
② 然后进行第二趟冒泡排序,对前n-1个记录进行同样的操作。
一般地,第i趟冒泡排序是对L->R[1 … n-i+1]中的记录进行的,因此,若待排序的记录有n个,则要经过n-1趟冒泡排序才能使所有的记录有序。
1.2 排序示例
设有9个待排序的记录,关键字分别为23, 38, 22, 45, 23,67, 31, 15, 41,冒泡排序的过程如图10-6所示。
1.3 算法实现
main.cpp
#include <iostream>
#include <time.h>
#define SIZE 10
void BubbleSort(int *a,int len)
{
int i,j,k,temp;
for (i=0; i<len-1; i++)
{
for (j = len-1; j>i; j--)
{
if (a[j-1]>a[j])
{
temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
}
}
printf("第%d步排序结果:",i);
for (k=1; k<len; k++)
{
printf(" %d",a[k]);
}
printf("\n");
}
}
int main(int argc, const char * argv[])
{
int shuzu[SIZE],i;
srand(time(NULL));
for (i=0; i<SIZE; i++)
{
shuzu[i] = rand() % 100;
}
printf("排序前的数组为:\n");
for (i=0; i<SIZE; i++)
{
printf(" %d",shuzu[i]);
}
printf("\n");
BubbleSort(shuzu, SIZE);
printf("排序后的数组为:\n");
for (i=0; i<SIZE; i++)
{
printf(" %d",shuzu[i]);
}
printf("\n");
// std::cout << "Hello, World!\n";
return 0;
}
运行效果(随机生成数据):
2.快速排序
2.1 快速排序思想
通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,再分别对这两部分记录进行下一趟排序,以达到整个序列有序。
2.2 快速排序过程
设待排序的记录序列是R[s…t] ,在记录序列中任取一个记录(一般取R[s])作为参照(又称为基准或枢轴),以R[s].key为基准重新排列其余的所有记录,方法是:
◆所有关键字比基准小的放R[s]之前;
◆所有关键字比基准大的放R[s]之后。
以R[s].key最后所
位置i作为分界,将序列R[s…t]分割成两个子序列,称为一趟快速排序。
2.3 一趟快速排序方法
从序列的两端交替扫描各个记录,将关键字小于基准关键字的记录依次放置到序列的前边;而将关键字大于基准关键字的记录从序列的最后端起,依次放置到序列的后边,直到扫描完所有的记录。
设置指针low,high,初值为第1个和最后一个记录的位置。
设两个变量i,j,初始时令i=low,j=high,以R[low].key作为基准(将R[low]保存在R[0]中)。
①从j所指位置向前搜索:将R[0].key与R[j].key进行比较:
◆ 若R[0].key≤R[j].key:令j=j-1,然后继续进行比较,直到i=j或R[0].key>R[j].key为止;
◆若R[0].key>R[j].key:R[j]ÞR[i],腾空R[j]的位置,且令i=i+1;
②从i所指位置起向后搜索:将R[0].key与R[i].key进行比较:
◆若R[0].key≥R[i].key:令i=i+1,然后继续进行比较,直到i=j或R[0].key<R[i].key为止;
◆若R[0].key<R[i].key:R[i]ÞR[j],腾空R[i]的位置,且令j=j-1;
2.4 一趟排序示例
2.4 代码:
main.cpp
#include <iostream>
#include <time.h>
#define SIZE 10
void QuickSort(int *arr,int left, int right)
{
int f,t;
int rtemp,ltemp;
ltemp = left;
rtemp = right;
f = arr[(left + right)/2]; //中间位置的值为分界值
while (ltemp < rtemp)
{
while (arr[ltemp] < f)
{
++ltemp;
}
while (arr[rtemp] > f)
{
--rtemp;
}
if (ltemp <= rtemp)
{
t = arr[ltemp];
arr[ltemp] = arr[rtemp];
arr[rtemp] = t;
--rtemp;
++ltemp;
}
}
if (ltemp == rtemp)
{
ltemp++;
}
if (left < rtemp)
{
QuickSort(arr, left, ltemp-1);
}
if (ltemp < right)
{
QuickSort(arr, rtemp +1,right );
}
}
int main(int argc, const char * argv[])
{
int shuzu[SIZE],i;
srand(time(NULL));
for (i=0; i<SIZE; i++)
{
shuzu[i] = rand() % 100;
}
printf("排序前的数组为:\n");
for (i=0; i<SIZE; i++)
{
printf(" %d",shuzu[i]);
}
printf("\n");
QuickSort(shuzu,0,SIZE-1);
printf("排序后的数组为:\n");
for (i=0; i<SIZE; i++)
{
printf(" %d",shuzu[i]);
}
printf("\n");
// std::cout << "Hello, World!\n";
return 0;
}
运行效果(随机生成数据):
参考书籍:《C/C++常用算法手册》 《数据结构-清华大学严蔚敏》