第八周数据结构笔记


排序的基本概念
(1)排序
有n个记录的序列{R1,R2,....,Rn},其相应关键字的序列是{K1,K2,....,Kn.},相应的下标序列为1, 2, .,n。 通过排序,要求找出当前下标序列1,2,....n 的一种排列
p1,p2, .,pn,使得相应关键字满足如下的非递减(或非递增)关系,即: K1≤K2≤...≤Kp,这样就得到一个按关键字有序的记录序列: {Rz, R2,Rn}。
(2)内部排序与外部排序
根据排序时数据所占用存储器的不同,可将排序分为两类。一类是整个排序过程完全在内存中进行,称为内部排序;另一类是由于待排序记录数据量太大,内存无法容纳全部数据,
排序需要借助外部存储设备才能完成,成为外部排序。
(3)主关键字与次关键字
上面所说的关键字K可以是记录R:的主关键字,也可以是次关键字,甚至可以是记录中若干数据项的组合。若K;是主关键字,则任何一个无序的记录序列经排序后得到的有序序列是
惟一的;若K;是次关键字或是记录中若干数据项的组合,得到的排序结果将是不惟一的,因为待排序记录的序列中存在两个或两个以上关键字相等的记录。
在排序过程中,一般进行两种基本操作:
①比较两个关键字的大小;
②将记录从一个位置移动到另一个位置。
其中操作①对于大多数排序方法来说是必要的,而操作②则可以通过采用适当的存储方
式予以避免。对于待排序的记录序列,有三种常见的存储表示方法。
●向量结构,即将待排序的记录存放在一组地址连续的存储单元中。由于这种存储方式中,记录之间的次序关系由其存储位置来决定,所以排序过程中一定要移动记录才行。
●链表结构。采用链表结构时,记录之间逻辑上的相邻性是靠指针来维持的,这样在排序时,就不用移动记录元素,而只需要修改指针。这种排序方式被称为链表排序。
●记录向量与地址向量结合,即将待排序记录存放在一组地址连续的存储单元中,同时另设一个指示各个记录位置的地址向量。这样在排序过程中不移动记录本身,而修改地址
向量中记录的地址, 排序结束后再按照地址向量中的值调整记录的存储位置。这种排序方式被称为地址排序。
代码定义:typedef int KeyType;
typedef struct {
KeyType key;
OtherType other_ _data;
} RecordType;
(1)直接插入排序
直接插入排序是一种最基本的插入排序方法,其基本操作是将第i个记录插入到前面i-1个已排好序的记录中。
代码:void
InsSort(RecordType r[], int length)
/*对记录数组r做直接插入排序,length为数组中待排序记录的数目*/
for( i=2; i<=length; i++)
r[0]=r[i]; j=i-1;
/*将待插入记录存放到监视哨r[0]中*/
while (r[0].key< rj.key) /* 寻找插入位置*/
r[j+1]=r[j]; j=j-1;
r[j+1]=r[0];
/*将待插入记录插入到已排序的序列中*/
}/* InsSort */
(2)折半插入排序
从关于查找的讨论中可知,对于有序表进行折半查找,其性能优于顺序查找。所以,可以将折半查找用于在有序记录r[..i-1]中确定 应插入位置,相应的排序法称为折半插入排序法。
代码:
void  BinSort (RecordType r[], int length)
/*对记录数组r进行折半插入排序,length 为数组的长度*/
for( i=2 ; i<=length; ++i)
{
x= r[i];
low=1; high=i-1;
while (low<=high )
/*确定插入位置*/
{mid=(low+high) / 2;
if( x.key< r[mid].key) high=mid-1;
else
low=mid+1;
for( j=i-1 ;j>=low;--j)
r[j+1]= r[j];
/*记录依次向后移动*/
r[|ow]=x; .
/*插入记录*/
}/* BinSort*/

(3)希尔排序
在待排序的关键字序列基本有序且关键字个数n较少时,其算法的性能最佳。希尔排序又称缩小增量排序法,是一种基于插入思想的排序方法。
void  Shlllnsert(RecordType r[], int length, int delta)
/*对记录数组r做一趟希尔插入排序,length 为数组的长度,delta为增量*/
for(i=1+delta ; i<= length; i++)
/*1+delta为第一个子序列的第二二个元素的下标*/
if([ij.key < r[i-delta].key)
{
r[0]= r[i];
/*备份r[i] (不做监视哨) */
for(j=i-delta; j>0 &&r[0].key < r[j].key ; j-=delta)
r[j+delta]= r[];
r[j+delta]= r[0];
}/*Shellnsert*/
void
ShellSort(RecordType r[], int length, int delta[], int n)
/*对记录数组r做希尔排序,length 为数组r的长度,delta 为增量数组,n为delta[]的长度*/
for(i=0; i<=n-1; ++i)
Shelllnsert(r, Length, delta[i]);
}




原文地址:https://www.cnblogs.com/juyuanyuan/p/13073161.html