链表无序。编一 PASCAL 过程,将链中结点分成一个奇数链和一个偶数链,分别由 P,Q指向,每个链中的数据按由小到大排列。

//分析:1、可知需要两步,先分成奇偶链表,然后进行排序,也或者先排完序然后再分奇偶链表都可以
//      2、边查找分析奇数还是偶数,然后利用之前的插入排序法分别插入奇数链表或者偶数链表


//这里我采用的第二种方法,感觉可能会相对简单方便一点,链表题的话我感觉只要你理解了链表的构成,一般来说这些题做起来也不会很难,一般思路还是好想到的,
//第一种方法的话你可以看之前额链表排序以及分链表的题,结合一下就行,有不会的话可以私信我,我有空的话写一下

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

struct LB
{
	int data;
	struct LB *next;
};

struct LB *Create();
void Shu(struct LB *head);
void Pascal(struct LB *head,struct LB *P,struct LB *Q);

int main()
{
	struct LB *Lian,*P=NULL,*Q=NULL;
	printf("请随意输入链表元素(输入-1回车结束输入):\n");
	Lian=Create();   //首先创建初始链表
	printf("链表创建结果如下:\n");
	Shu(Lian);   //测试创建成功与否
	Pascal(Lian,P,Q);  //重点来了,开始分奇偶链表同时排序,其实我感觉也就是再之前做的插入排序上多一点点步骤
	return 0;
}

struct LB *Create()
{
	struct LB *head=NULL,*p,*p1;   //这里带头结点与否都无关紧要,如果是排序的话,个人感觉带头结点好操作一些
	p=(struct LB *)malloc(sizeof(struct LB));
	scanf("%d",&p->data );    //注意千万不要省略取地址符号,我以前写的时候这里老是忘记了,切记多上机操作,可以发现自己哪里容易出错,手写不好查错
	p->next =NULL;
	while(p->data !=-1)
	{
		if(head==NULL)
		{
			head=p;
			p1=p;
		}
		else
		{
			p1->next =p;
			p1=p;
		}
		p=(struct LB *)malloc(sizeof(struct LB));
	    scanf("%d",&p->data );  
	    p->next =NULL;
	}
	return head;
}

void Shu(struct LB *head)
{
	struct LB *p;
	p=head;
	while(p!=NULL)
	{
		printf("%-3d",p->data );
		p=p->next ;
	}
	putchar('\n');
}

void Pascal(struct LB *head,struct LB *P,struct LB *Q)    //gogogo!不要看它多,奇偶链表操作差不多,你们有时间的话也可以把链表插入排序单独写一个函数然后直接套用
{
	struct LB *p,*j,*o,*temp,*z;
	P=(struct LB *)malloc(sizeof(struct LB));   //创建头结点,方便插入排序使用
	Q=(struct LB *)malloc(sizeof(struct LB));
	P->next =NULL;
	Q->next =NULL;
	p=head;
	while(p!=NULL)
	{
		temp=p;
		p=p->next ;
		temp->next=NULL;//取出结点,方便插入排序,以防打乱原先链表,若这是奇偶链表最后一个结点也可以收尾
//这一步也是写的时候发现取出结点更好,单独节点好操作,之前想的是直接在原链表上链接,那样因为需要排序所以很容易乱,果然还是要实践呀

		if(temp->data %2==0)  //表示是偶数
		{
			if(Q->next ==NULL)   //链表第一个结点,因此不用判断排序
			{
				Q->next =temp;
				o=temp;
			}
			else    //需要判断排序,用到之前的插入排序法,不过稍微有小改动
			{
				if(temp->data >o->data )
				{
					z=o;     //这里需要一个临时判断结点来判断大小插入,我这里有弄混过,因为结点名字不够明显,你们可以起明显一点的名字以防过程过用错指针
					while(z->next !=NULL)
					{
						if(z->next ->data >temp->data )
						{
							temp->next =z->next ;
							z->next =temp;
							z=temp;
							break;
						}
						z=z->next ;
					}
					if(z->next ==NULL)  //表示要在末尾处插入
					{
						z->next =temp;
						z=temp;
					}
				}
				else   //表示当前它最小,直接插入头部即可
				{
				  Q->next =temp;
				  temp->next =o;
				  o=temp;
				}
			}
		}


		else   //奇数链表
		{
			if(P->next ==NULL)   //链表第一个结点,因此不用判断排序
			{
				P->next =temp;
				j=temp;
			}
			else    //需要判断排序,用到之前的插入排序法,不过稍微有小改动
			{
				if(temp->data >j->data )
				{
					z=j;
					while(z->next !=NULL)
					{
						if(z->next ->data >temp->data )
						{
							temp->next =z->next ;
							z->next =temp;
							z=temp;
							break;
						}
						z=z->next ;
					}
					if(z->next ==NULL)  //表示要在末尾处插入
					{
						z->next =temp;
						z=temp;
					}
				}
				else   //表示当前它最小,直接插入头部即可
				{
				  P->next =temp;
				  temp->next =j;
				  j=temp;
				}
			}
		}
	}
	printf("奇链表链接结果如下:\n");     //这里因为我没有返回链表,所以直接在这里输入了,有想在主函数输入的可以改写一下函数然后返回给他,就可以在主函数输出了
	Shu(P->next );
	printf("偶链表链接结果如下:\n");
	Shu(Q->next );
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值