2020年王道数据结构(第二章 2.6)题解 ----c语言自顶向上归并排序链表

对于链表的排序其实是有很多方法的

可以用自顶向下递归的进行排序,也可以自底向上迭代的进行排序

或者用一个新的链表进行每一次插入的时候找到需要插入的位置

由于之前写过排序的算法,本来想写自底向上迭代的排序算法,结果我能力有限,没有写出来,就参照这写了一个自顶向上递归的排序算法

//自顶向下归并排序
//明天写自低向上归并排序

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>


typedef struct Node
{
	int data;
	struct Node* next;

}Node;


void print_list(Node* head);

//创建一个不带头节点的链表 返回链表的头指针
Node* Init_List()
{
	Node* head = (Node*)malloc(sizeof(Node));
	assert(head);

	int first,size;

	printf("please enter list sizes: ");
	scanf("%d",&size);


	head->data = 0;
	head->next = NULL;

	//采用尾插法,构建链表
	//则需要构建一个链表的尾指针
	Node* tail = head;

	for(int i = 0; i < size ; i++)
	{
		Node* new = (Node*)malloc(sizeof(Node));
		assert(new);

		scanf("%d",&first);
		new -> data = first;
		tail-> next = new;
		new -> next = NULL;
		tail = tail->next;

	}

	return head;

}

// //使用自低向上归并排序
// void merge_sort(Node* head,int n)
// {
// 	Node* p = head;

	 

// }


Node* merge(Node* head1 ,Node* head2)
{
	if(head1 == NULL) return head2;
	if(head2 == NULL) return head1;

	Node* res, *p;

	if(head1->data < head2->data)
	{
		res = head1;         //链接上了
		head1 = head1->next;
	}
	else
	{
		res = head2;
		head2 = head2->next;
	}

	p = res; //res作为头指针。用p来遍历建立链表

	while(head1 != NULL && head2 != NULL)
	{
		if(head1->data < head2->data)
		{
			p -> next = head1;        
			head1 = head1->next;
		}
		else
		{
			p -> next = head2;
			head2 = head2->next;
		}

		p = p->next;
	}

	if(head1 != NULL) p->next = head1;
	else if (head2 != NULL) p->next = head2;

	return res;
}

//使用自顶向下归并排序
Node* merge_sort(Node* head)
{
	if(head == NULL || head -> next == NULL) return head;
	else
	{
		//快慢指针找到中间节点.  巧妙
		Node* fast = head, *slow = head;
		while(fast->next != NULL && fast->next->next != NULL)
		{
			fast = fast->next->next;
			slow = slow->next;
		}

		fast = slow;
		slow = slow->next;
		fast->next = NULL;
		fast = merge_sort(head);//前半段排序
		slow = merge_sort(slow);

		return merge(fast,slow);
	}

	 

}

//在该算法中 这个函数没有用到
void list_length(Node* head,int* value)
{
	Node* p ;
	
	p = head->next;

	while(p != NULL)
	{
		*value = *value + 1;
		p = p->next;
	}

}

void print_list(Node* head)
{
	Node* p ;
	p = head->next;

	while(p != NULL)
	{
		printf("%d ", p->data);
		p = p->next;
	}

	printf("\n");

}


int main(int argc, char const *argv[])
{
	Node* list = Init_List();

	int n = 0;
	//list_length(list,&n);
	
	list = merge_sort(list);

	print_list(list);
	
	
	

	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

五月的天气

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

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

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

打赏作者

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

抵扣说明:

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

余额充值