方法:快慢指针的方法
快指针每次走2个结点,慢指针每次走1个结点,当快指针走完链表,慢指针刚好走到中间。
注意:当结点数是奇数时 慢指针 走到 中间结点,
当结点数是偶数时,此时中间结点有2个,此时慢指针指向靠前那个结点。
eg 1 3 5 7 9 快指针第一次走到 5 第二次走到 9 然后链表走完,慢指针走2步 刚好走到 中间结点5
1 3 5 7 快指针第一次走到 5 第二次越界只走一步然后链表走完,快指针走2步慢指针走1步,快指针走1步时慢指针没有 走,故慢指针 走到结点 3。
如果想 当结点个数为偶数个时,慢指针指向 中间2个结点靠后那个结点,那么当快指针走1步时,慢指针也走1步。
#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;
}