[关闭]
@quinn 2015-03-20T09:22:59.000000Z 字数 2010 阅读 2267

基本排序(四):索引指针排序、链表排序、关键字排序

排序算法

1. 索引和指针排序

2. 链表排序

应用范围和基本原理

算法实现

我们维持一个输入链表(h->next指向这个链表,有表头),一个输出链表(out指向这个链表)。当链表非空时,遍历链表找出最大元素(因为链表之前易于插入元素,先插大的,在大的之前依次插入小的),然后从输入表中去除这个最大元素,把他插入到输出表的前面。其中,找出最大元素函数findMax(),返回的是最大元素节点的上一节点的地址。(因为要想删除一个节点,必须知道它前一节点的地址prev->next = prev->next->next;

C程序实现

  1. link linklist_sort(link h)
  2. {
  3. link out, t, max;
  4. out = NULL, t = NULL, max = NULL;
  5. while(h->next != NULL)
  6. {
  7. max = findMax(h);
  8. t = max->next;//最大元素节点
  9. max->next = max->next->next;//删除max节点
  10. t->next = out;//将t插入到out前
  11. out = t;//返回out
  12. }
  13. h->next = out;
  14. return h;
  15. }

在一些表的处理中,我们不需要详细实现排序过程,只需要像插入排序依次向表中插入新元素,使表有序。

3. 关键字索引排序

原理

所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来。
被排序的对象--文件由一组记录组成。记录则由若干个数据项(或域)组成。其中有一项可用来标识一个记录,称为关键字项。该数据项的值称为关键字(Key)。
在待排序的文件中,若存在多个关键字相同的记录,我们希望通过按关键字索引排序,其中关键字是在一个小范围内的整数。
例如:
此处输入图片的描述
1)我们统计不同值的关键字个数分别是多少:6个0,4个1,2个2,3个3.
2)局部统计比其他关键字小的关键字的个数:0个关键字比0小,6个关键字比1小,10个关键字比2小,12个关键字比3小。
3)根据上述统计数作为索引将关键字放到合适位置:在开头0开始放具有0关键字的元素0,根据0,增加指针值,放下一个0关键字的元素3……);将具有3关键字的元素从位置12开始放起(12个比3小);以此类推

C程序实现

  1. void keyword_sort(Item a[], int l, int r)
  2. {
  3. Item b[r-l+1];
  4. int cnt[M];//M为关键字的个数
  5. for(int j = 0; j < M; j++)//初始化个数全0
  6. cnt[j] = 0;
  7. for(int i = l; i <= r; i++) //统计不同值的关键字个数,
  8. cnt[a[i]+1]++;
  9. for(int j = 1; j < M; j++)//统计比其他关键字小的关键字的个数,cnt[j]存储比j小的关键字的个数
  10. cnt[j] = cnt[j] + cnt[j-1];
  11. for(int i = l; i <= r; i++) //按关键字个数索引放到辅助数组b中
  12. b[cnt[ a[i] ]++] = a[i];
  13. for(int i = l; i <= r; i++)
  14. a[i] = b[i-l];
  15. }

如果要排序的文件很大,使用辅助数组b会导致内存分配问题,可以通过使用原位排序避免使用额外数组完成。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注