1. 程式人生 > >遍歷一次單鏈表,找出單鏈表中間的值

遍歷一次單鏈表,找出單鏈表中間的值

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);
}
執行結果如下;