排序分类
很多人对排序分类不是很清楚,其实我也不清楚,但是我可以发表一下自己的见解。排序算法分为两类,内部排序和外部排序。内部排序一般指的就是数据在内存里面的排序算法,数据量一般比较少。最大不多于2G,毕竟这就把用户进程地址全部占用了,其实根本不可能,卡死得。外部排序一般指的是数据在文件里面存放着,不排除数据库里面存放着。内部和外部的排序联系就是在这里了。大名鼎鼎的归并排序。
归并
外部排序先把数据分成可以加载到内存的一些数据段,每一个数据段先排序,最后呢,利用归并排序排好再次存放到文件当中。归并排序可以有很多路,作为研究文章一般都是最典型的二路排序,再多的话就需要和需求相关了。数据量很不幸一般都不知道,所以用的是单链表节点。可以看看二路归并的实现了。
实现
#include <stdio.h> #include <malloc.h> #include <memory.h> /************************************************************************ @ 链表节点 @ data -- 节点数据 @ next -- 下一个节点指针 ************************************************************************/ typedef struct node { int data; struct node* next; }node; /************************************************************************ @ 链表插入节点 ************************************************************************/ int node_insert(struct node* the_node,int data) { //找最后节点 struct node *cur_node=the_node; while (cur_node->next != NULL) { cur_node=cur_node->next; } //创建新节点 struct node* new_node=(struct node*)malloc(sizeof(struct node)*1); new_node->data=data; new_node->next=NULL; //添加新节点 cur_node->next=new_node; return 0; } /************************************************************************ @ 释放链表 ************************************************************************/ int node_free(struct node* the_node) { struct node* cur_node=NULL; while(the_node != NULL) { cur_node=the_node; the_node=the_node->next; free(cur_node); cur_node=NULL; } return 0; } /************************************************************************ @ 链表归并 ************************************************************************/ int list_merge(struct node* first,struct node* second,struct node** result) { //记录操作节点 struct node** cur_result=result; //选择小的 while(first != NULL && second != NULL) { if (first->data < second->data) { *cur_result=first; cur_result=&((*cur_result)->next); first=first->next; } else { *cur_result=second; cur_result=&((*cur_result)->next); second=second->next; } } //处理剩余 if (first != NULL) { *cur_result=first; } //处理剩余 if (second != NULL) { *cur_result=second; } return 0; } /************************************************************************ @ 主函数 -- 程序入口点 ************************************************************************/ int main() { //创建第一个链表 struct node* first=(struct node*)malloc(sizeof(struct node)*1); first->data=1; first->next=NULL; for (int i=2;i<10;i++) { node_insert(first,i); } //创建第二个链表 struct node* second=(struct node*)malloc(sizeof(struct node)*1); second->data=2; second->next=NULL; for (int i=14;i<100;i++) { node_insert(second,i); } //归并排序 struct node* result=NULL; list_merge(first,second,&result); //输出结果 struct node* out_result=result; while (out_result != NULL ) { printf("%d ___ ",out_result->data); out_result=out_result->next; } //释放链表 node_free(result); result=NULL; first=NULL; second=NULL; return 0; }
运行结果
有图为证
总结
1.二路归并最核心的就是merge里面的while循环了。比较大小。
2.再次就是剩余数据的处理,照样是while循环,我们不知道有多少个数据留下毕竟。
3.其他的就是单链表数据结构的典型构建了。
时间: 2024-10-03 02:10:03