第二章
- 文件的查找:对用户指定的文件中的记录进行查找,也称为检索。
- 插入记录:将一个新的记录插入到文件的指定位置。
- 记录的删除:从文件中删除指定的记录。
- 文件的排序:对文件中的记录按指定的关键字的顺序进行排序。
- 修改文件的记录:修改文件中记录的内容,并更新。
2.1 顺序查找
若每条记录的信息与它的关键字都存放在一个记录中,如下定义:
typedef struct
{
keytype key;
datetype date;
}RecordType;
记录的顺序查找算法可描述为:
int sq_search(RecordType Record[],int n,keytype key)//形参为要查找的记录,记录的容量,要查找的关键字
{
int i;
for(i=0;i<n;i++)
{
if(Record[i].key==key)return i;//查找成功
}
return -1;//查找失败
}
2.2 折半查找
减小查找序列的长度,分而治之地进行关键字地查找。它地查找过程是:先确定待查找记录所在的范围,然后逐渐缩小查找的范围,直至找到该记录为止。
如果每条记录的信息与它的关键字存放在一个记录中,如下定义:
typedef struct
{
keytype key;
datatype data;
}RecordType;
每个记录中包含一个关键字域key和一个数据域data。这种记录的折半查找算法可描述为:
int bin_search(RecordType r[],int n,keytype k)
{
int low=0,high=n-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(r[mid].key==k)return mid;
else if(k>r[mid].key)low=mid+1;
else high=mid-1;
}
return -1;
}
2.3 直接插入排序
步骤如下:
代码描述如下:
void insertsort(keytype k[],int n)//从小到大排序
{
int i,j,min;
keytype tmp;
for(i=1;i<=n-1;i++)
{
tmp=k[i];
j=i-1;
while(j>=0&&tmp<k[j])
{
k[j+1]=k[j];//选择k[i]插入的位置
j--
}
k[j+1]=tmp;//将元素查到指定的位置上,第i趟排序完成
}
}
2.3 选择排序
选择排序的步骤如下:
代码描述为:
void selectsort(DelemType a[],int n)
{
int i,j,min;
DelemType tmp;
for(i=0;i<n-1;i++)
{
min=i;
for(j=i+1;j<n;j++)
{
if(a[j]<a[min])
min=j;//min用来记录最小元素的位置
}
if(min!=j)
{
tmp=a[min];
a[min]=a[i];
a[i]=tmp;//交换a[i]和a[min]的位置
}
}
}
2.4 冒泡排序
步骤如下:
代码描述如下:
void bubblesort(ElemType a[],int n)//从小到大排序
{
ElemType tmp;
int i,j;
for(i=0;i<n-1;i++)
{
for(j=1;j<n-i;j++)
{
if(a[j-1]>a[j])
{
tmp=a[j-1];
a[j-1]=a[j];
a[j]=tmp;
}
}
}
}
2.5 希尔排序
将要排序的序列按一定的增量划分为若干个子序列,在子序列中采用其他的排序方法(如直接插入排序或冒泡排序),子序列全部排序完成后,然后减小增量gap,重新对上述序列进行划分->对子序列进行排序->减小gap->划分序列,直至间隔数量减小为1为止;
void shellsort(ElemType a[],int n)
{
int i,gap=n;
ElemType tmp;
while(gap>1)
{
gap=gap/2;
for(i=0;i<n-gap;i++)//直接插入排序;
{
tmp=a[i+gap];
for(j=i;j>=0;j-=gap)
{
if(tmp<a[j])
{
a[j+gap]=a[j];
}
}
a[j+gap]=tmp;
}
}
}
2.6 快速排序
快速排序的基本思想是将一组数列{k1,k2,k3,……,kn}任取一个元素,将这个元素称为基准元素或者支点,把小于基准元素的元素都移动到基准元素的前面,大于基准元素的元素都移动到基准元素的后面,这样经过一轮排序之后,基准元素的位置就是它的最终位置,并且将当前参加排序的数列分为两个数列,前面的数列都小于基准元素,后面的数列都大于基准元素。接下来对这两个序列重复上面的排序操作,直到所有元素都被移动到排序后他们应处的位置上。
在排序过程中,每次按照基准元素将排序序列划分为前后两个子序列的过程称为一次划分过程,一次划分的操作如下:
至此完成了原序列的第一次划分,接下来对元素5前后两个序列重复上述步骤,直至所有元素都移动到了最终的位置上。
序列的每一次划分都是按照 步骤1->步骤2->步骤1->步骤2->步骤1->步骤2->……->步骤3->结束 进行的。也就是说当i>j时,基准元素才会被移动到最终位置上。
上述的排序过程用C语言描述如下(递归):
void quicksort(keytype k[],int s,int t)//快速排序,s为基准元素下标,t为要排序的序列元素最后一个元素的下标
{
int i,j;
if(s<t)
{
i=s;
j=t+1;
while(1)
{
do
i++;
while(!(k[i]>=k[s]||i==t))
do
j--;
while(!(k[j]<=k[s]||j==s))
if(i<j)
swap(k[i],k[j]);//如果i<j,则交换k[i]和k[j]的位置
else
break;
}
swap(k[s],k[j]);//交换基准元素和k[j]的位置;
quicksort(k,s,j-1);//继续对基准元素前面的元素执行以上操作
quicksort(k,j+1,t);//对基准元素后面的元素执行以上操作
}
}