实验11-10-链表排序

题目描述

已知一个正整数组成的无序序列,个数未知,但至少有一个元素,你的任务是建立一个单链表,并使用该链表存储这个正整数序列,然后将这个链表进行排序,使得排序后的链表为递增序列。正整数的输入用-1作为结束标志,注意-1不算这个正整数序列中的元素(不要统计-1)。在排序的过程中,你可以自己选择排序算法(冒泡排序、选择排序等),但必须是通过修改结点的指针域来进行排序,而不是对结点的数据域进行修改。程序结束后要释放所有节点占据的空间。

输入

一个元素个数未知的正整数序列,以输入“-1”结束,输入“-1”前至少输入一个正整数。

输出

经过排序后的链表,每个元素后有一个空格,注意最后一个元素后只有换行符。
数据最多的测试用例节点数在1000这个数量级,所有整数可以用int型存储。
请注意输入输出格式。

样例输入

49 38 65 97 76 13 27 49 -1

样例输出

The new list is:13 27 38 49 49 65 76 97

方法一:有序插法

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node* next;
}Node,*Link;
void insertup(Link head,int x);//有序插
void printlist(Link head);
int main()
{
	Link head=malloc(sizeof(Node));
	head->next=NULL;
	int arr[1000],i=0;
	scanf("%d",&arr[i]);
	while(arr[i]!=-1){
		insertup(head,arr[i]);
		i++;
		scanf("%d",&arr[i]);
	}
	printlist(head);
	return 0;
} 
void insertup(Link head,int x)
{
	Link p=head->next;
	Link q=head;

    //创建一个新节点,用于存放数据
	Link tmp=malloc(sizeof(Node));
	tmp->data=x;
	tmp->next=NULL;
	while(p!=NULL&&x>p->data){
		q=p;
		p=p->next;
	}
	tmp->next=p;
	q->next=tmp;
}
void printlist(Link head)
{
	Link p=head->next;
	printf("The new list is:");
	while(p!=NULL){
		if(p->next==NULL)
		{
			printf("%d\n",p->data);
			break;
		}
		else
		printf("%d ",p->data);
		p=p->next;
	}
}

方法二:选择排序法

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node* next;
}Node,*Link; 
void insertlist(Link head,int count,int arr[]);//尾插法创建链表 
void selectsort(Link head,int arr[]);//选择排序
void printlist(Link head); 
void freelist(Link head);//释放链表 
int main()
{
	int arr[10000],i=0;
	Link head=malloc(sizeof(Node));
	head->next=NULL;
	scanf("%d",&arr[i]);
	while(arr[i]!=-1){
		i++;
		scanf("%d",&arr[i]);
	}//i累计-1前元素个数
	insertlist(head,i,arr); 
	selectsort(head,arr);
	printlist(head);
	freelist(head);
	return 0;
}
void insertlist(Link head,int count,int arr[])
{
	Link p,q=head;
	int i=0;
	while(i<count){
		p=malloc(sizeof(Node));
		if(p!=NULL)
		{
			p->data=arr[i];
			p->next=NULL;
			q->next=p;
			q=p;
			i++;	
		}
	}
}
void selectsort(Link head,int arr[])
{
	Link p;
	Link q=head->next;
	Link min;
	Link prep,preq=head,nextp,nextq,premin,nextmin;
	while(q!=NULL){
        //每次循环初始化,确定min,prep,p
		min=q;
		prep=q;
		p=q->next;

		while(p!=NULL){
			if(min->data>p->data)
			{
                //更新min的前驱和min
				min=p;
				premin=prep;
			}
			prep=p;
			p=p->next;
		}
		if(min!=q)//需要将min节点与q节点交换
		{
			nextq=q->next;nextmin=min->next;//确定q和min的后继

			if(nextq==min)
			nextq=q;//若两点相邻,避免成环
			
            //交换
			preq->next=min;min->next=nextq;
			premin->next=q;q->next=nextmin;

			//更新q,为下次循环作准备 
			preq=min;q=nextq; 
		}
		else//不需要交换
		{
			preq=q;
			q=q->next;
		}
	}
}
void printlist(Link head)
{
	Link p=head->next;
	printf("The new list is:");
	while(p!=NULL){
		if(p->next==NULL)
		{
			printf("%d\n",p->data);
			break;
		}
		else
		printf("%d ",p->data);
		p=p->next;
	}
}
void freelist(Link head)
{
	Link p=head->next;
	Link q=head;
	while(p!=NULL){
		q=p;
		p=p->next;
		free(q);
	}
	head->next=NULL;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值