线性表L=(a1,a2,a3,...,an-2,an-1,an)变成L=(a1,an,a2,an-1,a3,an-2,...)

//头尾递减前置排列函数
void HeadAndTailPutFront(LNode *pp){
	LNode *LL1,*LL2,*LL3,*ppnext;
	int length,i=0,k=1,times,parity;
	ElemType ee;      // 创建一个数据元素。
	LL1=InitList1(); // 初始化链表开一个新的空间去存正序的链表 
    LL3=InitList1();     // 初始化链表。
	length=LengthList(pp);//计算链表长度
	parity=length%2;//用parity取余2链表长度,偶数为0奇数为1,来代表链表的奇偶性 
	printf("进入函数成功%d\n",length);
	PrintList(LL1);
	ppnext=pp->next;
	while(ppnext!=NULL){
		i++;//i从1开始 
		ee=ppnext->data;//把头结点之后的第一个值赋给ee 
		printf("i的值%d\n",i);
		InsertList(LL1,i,&ee);
		PrintList(LL1);
		ppnext=ppnext->next;	
	} //在修改原来的代码时,真可谓是牵一发而动全身啊,尽量要一气呵成啊啊啊啊啊,找BUG太痛苦了嘤嘤嘤 
	PrintList(LL1);
	ReverseList(pp); /*注意这个函数是在链表原地进行翻转的,
	所以前面未翻转的要单独保存不能直接存头结点*/ 
	LL2=pp;// 
	PrintList(pp);
	times=length/2;
	printf("times值%d\n",times);
	PrintList(LL3);//此时为空的 
	for(i=0;i<times+parity;i++){//这边要给i重新归零 ,如果是奇数长度链表则循环次数加1 
		LL1=LL1->next;//从头结点之后的第一个开始 
		ee=LL1->data;//把头结点之后的第一个值赋给ee 
		InsertList(LL3,k,&ee);//k从1开始 
		printf("ee的值为%-3d\n",LL1->data);
		LL2=LL2->next;//从头结点之后的第一个开始
		ee=LL2->data;//把头结点之后的第一个值赋给ee 
		InsertList(LL3,k+1,&ee);//尾部的数是要在后一个位置 
		k=k+2;//往后移动两个位置确保不重叠数据 
		printf("ee2的值为%-3d\n",LL2->data);
		}
    if(parity)DeleteNode(LL3,k-1);//如果长度是奇数个,就把最后一个重复的删除 
	printf("*************\n");
	printf("最后输出结果为\n"); 
	PrintList(LL3);
}
// 把链表pp结点之后的结点[原地逆置](反转),返回值:0-失败;1-成功。
void ReverseList(LNode *pp)
{
//	printf("翻转前的头结点为%d\n地址为%p\n",*pp,pp); 
  LNode *ss;      // 当前结点。
  LNode *ssnext;  // 当前结点的下一结点。

  ss=pp->next;    // 从pp结点之后的结点开始反转。

  pp->next=NULL;  // pp->next指向空。

  while (ss != NULL)
  {
    ssnext=ss->next;  // 保留ss下一结点的地址。

    // 以下两行相当于在pp之后插入ss结点。
    ss->next=pp->next;
    pp->next=ss;

    ss=ssnext;  // ss结点后移。
  }
//  printf("翻转后的头结点为%d\n地址为%p\n",*pp,pp); 
}
// 打印链表中全部的元素。
void PrintList(LinkList LL)
{
  if (LL == NULL) { printf("链表LL不存在。\n"); return; } // 判断链表是否存在。

  LNode *pp=LL->next;  // 从第1个结点开始。

  while (pp != NULL)
  {
    printf("%-3d", pp->data);  // 如果元素ee为结构体,这行代码要修改。
    pp=pp->next;
  }

  printf("\n");

  /*
  // 以下代码用于显示全部结点的地址和元素的值。
  LNode *pp=LL;  // 从第0个结点开始。

  while (pp != NULL)
  {
    printf("%p,%p,%-3d\n",pp,pp->next,pp->data);  // 如果元素ee为结构体,这行代码要修改。
    pp=pp->next;
  }
  */
}
// 求链表的长度,返回值:>=0-表LL结点的个数。
int  LengthList(LinkList LL)
{
  if (LL == NULL) { printf("链表LL不存在。\n"); return 0; } // 判断链表是否存在。

  LNode *pp=LL->next;  // 头结点不算,从第1个结点开始。

  int length=0;

  while (pp != NULL) { pp=pp->next; length++; }

  return length;

  // 不使用临时变量,如何计算链表(包括头结点)的长度?
  // if (LL==NULL) return 0;
  // return LengthList(LL->next)+1;
}

引用了一些写好的函数,可声明后使用。

本题的算法思想是,把原来的链表翻转,然后和原来的链表分别依次插入到新的链表里面。

详见注释

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值