方法一:首先遍歷一次,求得單鏈表長度len,然後再遍歷一次,找到(len+1)/2的中間位置。
方法二:和找第k個結點類似,但是因爲是中間結點,又有一定的特殊性。定義兩個結點指針p和q,最開始都表示頭指針,然後,p每次移動一位,q每次移動兩位;當q移到最後一個結點時,p結點就在中間位置。
具體代碼實現如下:
#include <stdlib.h>
#include<iostream>
typedef int ElemType;
struct Node
{
ElemType data;
struct Node *next;
};
typedef struct Node Node;
typedef struct Node* Linklist;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MaxSize 30 //存儲空間初始分配量
typedef int Status;
Status InitList1(Linklist *L)
{
*L= (Linklist)malloc(sizeof(Node)); //產生頭結點,並且使得L指向該頭結點
if (!(*L))
return ERROR; //令頭結點的指針域爲空
(*L)->next = NULL;
return OK;
}
//獲取鏈表的長度
int ListLength1(Linklist L)
{
Linklist p;
p=L->next;
int len=0;
while(p)
{
p=p->next;
len++;
}
return len;
}
//對鏈表進行頭插法
Status ListInsert1(Linklist *L,int i, ElemType e)
{
Linklist p,s;
p=(*L);
int j=1;
while(p && j<i)
{
p=p->next;
j++;
}
if (!p || j>i)
return ERROR;
s=(Linklist)malloc(sizeof(Node));
s->data=e;
s->next =p->next;
p->next =s;
return OK;
}
/* 從頭到尾輸出鏈表元素 */
Status ListTraverse1(Linklist L)
{
Linklist p;
p=L->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
return OK;
}
/*找到鏈表中間元素並輸出*/
using namespace std;
void findListMiddle(Linklist L,int &num)
{
int count=0;
Linklist p=L;
int len=ListLength1(L);
int mid=(len+1)/2;
for (int i=1;i<=mid;i++)
{
p=p->next;
count++;
}
num=p->data;
cout<<num<<endl;
//cout<<count<<endl;
}
void findListMiddle2(Linklist L, int &num)
{
Linklist p=L;
Linklist q=L;
while(L != NULL && q!=NULL && q->next!=NULL) //注意這裏要用與運算!!而不是或。
{
p=p->next;
int i =p->data;
q=q->next->next;
// int j=q->data;
}
num=p->data;
cout<<num<<endl;
}
int main()
{
Linklist L;
InitList1(&L); //首先,要初始化一個鏈表
int len1=ListLength1(L);
printf("初始化鏈表長度爲:%d\n",len1);
//在表頭位置依次插入12345,最後,鏈表中存放的是5->4->3->2->1
for (int i=1;i<=6;i++)
{
ListInsert1(&L,1,i);
}
printf("\n第一次插入數據,長度爲:");
int len2=ListLength1(L);
printf("%d\n",len2);
printf("\n對正序的鏈表輸出:");
Linklist p =L;
for(int i=1;i<=len2;i++)
{
printf("%d ",p->next->data);
p=p->next;
}
printf("找到單鏈表中間結點:方法一\n");
int num1=0;
findListMiddle(L,num1);
printf("找到單鏈表中間結點:方法二\n");
int num2;
findListMiddle2(L,num2);
getchar();
}