方法: 快慢指针的方法。
快指针每次走2个结点,慢指针每次走1个结点,当快指针走完链表,慢指针刚好走到中间。
注意:
当结点数是奇数时,慢指针走到中间结点,当结点数是偶数时,此时中间结点有2个,此时慢指针指向靠前那个结点。
例如:1 3 5 7 9 快指针第一次走到 5 ,第二次走到 9 然后链表走完,慢指针走2步 刚好走到中间结点5。
再例如:1 3 5 7 快指针第一次走到 5 ,第二次越界只走一步即链表走完,而慢指针也走一步即走到3即走完,那么3就是那个慢指针指向靠前那个结点。
代码思路:
//快慢指针开始都指向 链表第一个结点
LinkNode* fast = list->next;
LinkNode* slow = list->next;
isOdd = false;
while(fast->next != NULL)
{
//在不越界的情况下快指针每次走2个结点
if(fast->next->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
//奇数个节点
else
{
cout<<slow->data;
isOdd = true;
}
}
//此时慢指针指向靠前的那个结点
if (!isOdd)
{
cout<<slow->data;
slow = slow->next;
cout<<slow->data;
}
代码实现:
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
//单链表结点结构
typedef struct LinkNode
{
int data;
LinkNode* next;
}LinkNode, *LinkList;
//采用尾插法创建单链表
bool CreateLinkList(LinkList* list, unsigned int num)
{
if(!list || num < 1)
{
return false;
}
LinkNode* node = new LinkNode(); //创建头结点
*list = node; //链表指向头结点
node->next = NULL;//初始化空链表
//设置随机种子
srand((size_t)time(NULL));
for(size_t i=0; i<num; i++)
{
//创建结点且赋值初始化
LinkNode* temp = new LinkNode();
temp->next = NULL;
temp->data = rand() % 100;
//新生成的结点放在单链表尾部
node->next = temp;
node = temp;
}
return true;
}
bool GetMidVal(LinkList list, int *data)
{
//参数检验
if(list == NULL)
{
return false;
}
//快慢指针开始都指向 链表第一个结点
LinkNode* fast = list->next;
LinkNode* slow = list->next;
while(fast->next != NULL)
{
//在不越界的情况下快指针每次走2个结点
if(fast->next->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
//当结点为偶数个时,在倒数第二个结点无法走2个结点,就走一个结点
else
{
fast = fast->next;
slow = slow->next;
}
}
*data = slow->data;
return true;
}
void ShowLinkList(LinkList list)
{
LinkNode* node = list->next;//node开始指向第一个结点
while (node)
{
cout << node->data << " ";
node = node->next;
}
cout << endl;
}
void deleteLinkList(LinkList list)
{
LinkNode* node = list->next;//node开始指向第一个结点
while (node)
{
LinkNode* del = node;
node = node->next;
delete del;
}
}
int main()
{
LinkList list;
int mid = 0;
CreateLinkList(&list,10);
GetMidVal(list, &mid);
ShowLinkList(list);
cout << mid << endl;
deleteLinkList(list);
return 0;
}