线性算法 排序之归并

排序分类

很多人对排序分类不是很清楚,其实我也不清楚,但是我可以发表一下自己的见解。排序算法分为两类,内部排序和外部排序。内部排序一般指的就是数据在内存里面的排序算法,数据量一般比较少。最大不多于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.其他的就是单链表数据结构的典型构建了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

当当小螳螂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值