问题描述:快速找到未知长度的单链表的中间结点
普通方法:首先遍历一遍单链表,以确定单链表的长度L,然后再从头结点出发,循环L/2次,找到单链表的中间结点。
高效算法(快慢指针):设置两个指针,*search,*mid都指向单链表的头结点。其中*search指针的移动速度是*mid指针移动速度的2倍。当*search移动到链表末尾时,*mid刚好在中间结点。(标尺的思想)
//快速得到单链表的中间结点 Status GetMidNode(LinkList &L,int &e){ LinkList search,mid; search = L; mid = L;//初始时候,search和mid都指向链表的头结点 while(search->next != NULL){ if(search->next->next != NULL){ search = search->next->next; mid = mid->next; } else search = search->next; } e = mid->data; return OK; }
实例:
#include<iostream> #include<stdio.h> #include<time.h> #include<stdlib.h> #include<string.h> #define OVERFLOW -2 using namespace std; typedef struct Node{ int data; struct Node *next; }Node,*LinkList; void ListInit(LinkList &L){ L = (LinkList)malloc(sizeof(Node)); if(!L) exit(OVERFLOW); L->next = NULL; } void ListCreate(LinkList &L, int n){//尾插法 LinkList r,p; r = L; srand(time(0));//初始化随机数种子 for(int i = 0; i < n; i++){ p = (LinkList)malloc(sizeof(Node)); p->data = rand()%100+1;//产生1-100的随机数 r->next = p; r = p; } r->next = NULL; } void PrintList(LinkList &L){ cout<<"生成的单链表:"<<endl<<endl; LinkList p; p = L->next; while(p){ cout<<p->data<<" "; p = p->next; } cout<<endl; } void GetMidNode(LinkList &L,int &e){ LinkList search,mid; search = L; mid = L; while(search->next != NULL){ if(search->next->next != NULL){ search = search->next->next; mid = mid->next; } else search->next; } e = mid->data; } int main(){ int e; LinkList L; ListInit(L); ListCreate(L,10); PrintList(L); cout<<endl; cout<<"中间值:"; GetMidNode(L,e); cout<<e<<endl; return 0; }