1,算法描述:给定一个单链表,但不知该表的大小,现要求只遍历一次,找出位于单链表中间的值。
基本思想:设置两个指针p,q,初始时,分别指向头结点,循环使p后移两位,q后移一位,当单链表遍历完毕时,q的位置就是中间位置。注意:当单链表长度为偶数时,在最后一次循环前,p已在最后一个结点上,此时p=p->next->next,是错误的,因为p->next 都不存在,怎么判断p->next的下一个结点是否存在呢;当单链表长度为奇数时,在最后一次循环前,p处在倒数第二个结点上,因为p->next存在,所以p=p->next->next是合法的,只不过此时p->next->next=NULL。那怎么解决这个问题呢,就要分两种情况,当p->next存在和不存在两种情况,当p->next存在,就让p=p->next-next;q=q-next;否则p=p->next;循环结束条件是p不存在。另外,当单链表为偶数时,中间的结点应该有两个,奇数时,中间结点为1个,在本算法中,加了一个标志iseven,判断该单链表的长度是奇数还是偶数,iseven=1;是偶数,则在输出时,要输出两位;iseven=0,单链表长度为奇数,则输出一位。
代码如下:
#include "stdafx.h"
#include<stdio.h>
#include <malloc.h>
#define SIZE 100
#define INCREMENT_SIZE 10
typedef struct LNode
{
int data;
LNode *next;
}LNode,*LinkList;
//creat a LinkList
bool creatLinklist(LinkList&L,int n)
{
LinkList p,q,t,s;
L=(LNode*)malloc(n*sizeof(LNode));
if(!L)
return false;
q=L;
for(int i=1;i<=n;i++)
{
p=(LNode*)malloc(sizeof(LNode));
scanf("%d",&p->data);
L->next=p;
L=p;
}
p->next=NULL;
L=q;
return true;
}
int findMidNode(LinkList&L,LinkList &q)
{
LinkList p;
int iseven=0;
p=L;
q=L;
while(p!=NULL)
{
if(p->next)//if(!p->next),p->next->next is illege
{
p=p->next->next;
q=q->next;
}
else
{
p=p->next;
iseven=1;// the length of LinkList is even
}
}
return iseven;
}
void main()
{
LinkList Llist,p,t;
int k;
int len;
int elemet;
int position;
printf("input the number of LinkList to be created:");
scanf("%d",&k);
creatLinklist(Llist,k);
printf("\n");
len=findMidNode(Llist,t);
if(len==1)
printf("%d,%d\n",t->data,t->next->data);
else
printf("%d\n",t->data );
free(Llist);
}
运行结果如下;