您的位置:首页 > 职场人生

【面试题】-求未知长度的链表的中间节点(快慢指针)

2015-06-11 16:59 471 查看

快慢指针

所谓的快慢指针的快慢是指指针向前移动的步长。比如在单链表中,快指针每次向前移动2个步长,慢指针则每次向前移动1个步长。

解题思路

快速找出未知长度的链表的中间节点,暴力解法就是先遍历真个链表,算出链表的长度,再从头遍历长度的一半,即可找出,不过这个比较费时。更巧妙的办法是运用快慢指针,将快慢指针先指向头结点,快指针移动2个步长,慢指针移动1个步长,当快指针指向链表末尾的时候,慢指针刚好就在中间节点上。

代码实现

1. 暴力解法

[code]void Find_mid(LinkList L) {
    LinkList p;
    int count, mid;
    int i = 0;

    if (L == NULL) {
        exit(ERROR);
    }

    p = L->next;
    count = 0;
    while (p) {
        count ++;
        p = p->next;
    }

    p = L->next;
    mid = count / 2 ;
    for (i = 0; i < mid; i++ )
    {
        p = p->next;
    }

    printf("%d\n", p->data);

}


2. 快慢指针

[code]void Find_mid2(LinkList L) {
    LinkList slow, fast;

    if (L == NULL) {
        exit(ERROR);
    }

    fast = slow = L;
    while(fast->next != NULL && fast->next->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
    }

    slow = slow->next;
    printf("%d\n", slow->data);
}


测试代码

[code]#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define  OK  1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef struct Node {
    int data;
    struct Node *next;
} Node, *LinkList;

/*随机产生n个元素的带表头的单链表(头插法)*/
void CreatList_Head(LinkList *L, int n) {
    LinkList p;
    int i;

    srand(time(0));

    (*L) = (LinkList)malloc(sizeof(Node));
    if (!(*L)) {
        exit(ERROR);
    }

    (*L)->next = NULL;

    for (i = 0; i < n; i++) {
        p = (LinkList)malloc(sizeof(Node));
        if (!p) {
            exit(ERROR);
        }
        p->data = rand() % 100 + 1;
        p->next = (*L)->next;
        (*L)->next = p;
    }
}

/*随机产生n个元素的带表头的单链表(尾插法)*/
void CreatList_Tail(LinkList *L, int n) {
    LinkList p, r;
    int i;

    srand(time(0));

    (*L) = (LinkList)malloc(sizeof(Node));
    if (!(*L)) {
        exit(ERROR);
    }
    r = (*L);

    for (i = 0; i < n; i++) {
        p = (LinkList)malloc(sizeof(Node));
        if (!p) {
            exit(ERROR);
        }
        p->data = rand() % 100 + 1;
        r->next = p;
        r = p;
    }

    r->next = NULL;
}

void Print_List(LinkList L) {
    LinkList p;
    if (!L) {
        exit(ERROR);
    }

    p = L->next;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }

    printf("\n");
}

void Print_List_noHead(LinkList L) {
    LinkList p;
    if (!L) {
        exit(ERROR);
    }

    p = L;
    while (p) {
        printf("%d ", p->data);
        p = p->next;
    }

    printf("\n");
}

void Find_mid(LinkList L) {
    LinkList p;
    int count, mid;
    int i = 0;

    if (L == NULL) {
        exit(ERROR);
    }

    p = L->next;
    count = 0;
    while (p) {
        count ++;
        p = p->next;
    }

    p = L->next;
    mid = count / 2 ;
    for (i = 0; i < mid; i++ )
    {
        p = p->next;
    }

    printf("%d\n", p->data);

}

void Find_mid2(LinkList L) {
    LinkList slow, fast;

    if (L == NULL) {
        exit(ERROR);
    }

    fast = slow = L;
    while(fast->next != NULL && fast->next->next != NULL){
        slow = slow->next;
        fast = fast->next->next;
    }

    slow = slow->next;
    printf("%d\n", slow->data);
}

int main(int argc, char const *argv[])
{
    LinkList L;
    CreatList_Head(&L, 11);
    Print_List(L);
    Find_mid(L);
    Find_mid2(L);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: