基本介绍
排序(sorting)是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列重新排列成一个按关键字有序的序列。在待排序的文件中,若存在多个关键字相同的记录,经过排序后,这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生改变,则称这种排序方法是不稳定的。
查找(searching)根据给定的某个值,在查找表(一个数据集合)中确定一个其关键字等于给定值的记录或数据元素。
1. 基本排序算法
1.1 插入排序
插入排序的基本思想是:每次将一个待排序的记录,按其关键字大小插入前面已经排好序的子文件中的适当位置,直到全部记录插入完成为止。
示例:
void insert_sort(int a[10]) {
for(int i = 2; i <= 10; i++) {
int j = i - 1;
a[0] = a[j]; //赋给0设置哨点
while(a[0] < a[j]) {
a[j + 1] = a[j]; //元素后移
a[j] = a[0];
j--;
}
}
}
1.2 冒泡排序
冒泡排序的基本思想是:依次比较相邻的两个数,将大的数放在后面,小的数放在前面。首先比较第一个和第二个数,然后比较第二个和第三个数,如此继续,直至比较最后两个数。用二重循环实现,外循环变量设置为i,内循环变量设置为j。外循环重复n - 1次,内循环依次重复n - 1,n - 2,n - 3,……,1次。每次进行比较的两个元素都是与内循环j有关的。
示例:
void bubble_sort(int n, int a[]) {
for(int i = 0; i < n -1; i++) {
for(int j = i + 1; j < n; j++) {
if(a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
1.3 快速排序
快速排序是目前比较好的排序算法,它是由C.A.Hoare发明并命名的。
快速排序的基本思想是:通过一次分隔,将无序序列分成两部分,其中前一部分的元素值均不大于后一部分的元素值。然后,对每一部分利用同样的方法进行分割,这个过程一直做到每一个子序列的长度小于某个值m为止。
对序列p的分割过程:首先,在序列的第一个、中间一个和最后一个元素中选取中项,得p(k),然后设置两个指针i和j分别指向序列的起始和最后的位置。
示例:
int Quick_Sort(ElemType A[], int left, int right) {
tmp = A[(left + right) / 2];
do {
while(A[i] < tmp && i < right) i++;
while(A[j] > tmp && j > left) j--;
if(i <=j) {
swap(A[i], A[j]);
i++;
j--;
}
}while(i <= j);
if(left < j) Quick_Sort(A, left, j);
if(i < right) Quick_Sort(A, i, right);
return l;
}
说明:在实际运用过程中一般不需要写快速排序算法,C语言中可以用qsort函数,C++中可以用sort函数,来减少编写代码所用的时间。
1.4 其他排序
排序的算法还有很多,如希尔排序,选择排序,堆排序、归并排序、桶排序等。此处不一一列举,读者可以查阅相关资料。
2. 基本查找算法
2.1 顺序查找
顺序查找的过程为:从表中第一个(最后一个)记录开始,逐个进行记录的关键字和给定值的比较,若两个值相等,则查找成功。
示例:
int Order_Search(int array[], int n, int key)
{
int i;
array[n] = key; //监视哨
//for循环后面的分号必不可少
for(i = 0; key != array[i]; i++) ;
return (i < n ? i: -1);
}
2.2 折半查找
折半查找法也称为二分查找法,它充分利用了元素间的次序关系(要求数据集合有序),采用分治策略,可以再最坏的情况下用O(log n)完成搜索任务。二分搜索法的应用极其广泛,而且它的思想易于理解。
基本思想:将n个元素分成个数大致相同的两半,取a[n / 2]与欲查找的key作比较,如果key = a[n / 2],则找到x,算法终止;如果key < a[n /2],则只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排序);如果key > a[n / 2],则只要在数组a的右半部继续搜索x。
示例:
int BinarySearch(int a[], int key, int n)
{
int left = 0;
int right = n - 1;
while(left <= right) {
int middle = (left + right) / 2;
if(key == a[middle])
return middle;
if(key > a[middle]
left = middle + 1;
else
right = middle - 1;
}
return -1;
}