数据结构与算法7——单链表小结(腾讯面试题)

这篇博客讨论了如何在面试中解答寻找未知长度单链表中间结点的问题。首先介绍了简单方法,即遍历两次链表,算法复杂度为O(3L/2)。接着提出优化方案,使用快慢指针,快指针移动速度是慢指针的2倍,当快指针到达末尾时,慢指针位于中间。提供了实现代码,并分享了编写链表代码时遇到的节点定义和类型匹配问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:快速找到未知长度单链表的中间结点。

既然是面试题就一定有普通方法和高级方法,而高级方法无疑会让面试官大大加分!

普通的方法很简单,首先遍历一遍单链表以确定单链表的长度L。然后再次从头结点出发循环L/2次找到单链表的中间结点。

算法复杂度为:O(L+L/2)=O(3L/2)。

能否再优化呢?有一个很巧的方法:利用快慢指针

利用快慢指针原理:设置两个指针*search、 *mid 都指向单链表的头结点。其中 *search 的移动速度是 *mid 的2倍。当 *search 指向末尾结点的时候,*mid 正好就在中间了。

实现代码:
GetMidNode.c

int GetMidNode( LinkList L ,ElemType *e )
{
	LinkList search,mid;
	mid = search = L;
	
	while( search->next != NULL )
	{
		if( search->next->next != NULL ) 
		{
			search = search->next-next;
			mid = mid->next;
		}
		else
		{
			search = search->next;
		}
	}
	*e = mid->data;
	return 1;
}

接下来就写一个完整的代码:实现随机生成20个元素的链表(尾插法或者头插法任意),用我们刚才学到的方法快速查找中间结点的值并且显示。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define OK 1;

typedef struct _Node 
{
    int           data;      // 数据域   
    struct _Node  *Next;     // 指针域,指针指向的是下一个结点
}Node;


Node* create_list_head( int num )
{
        Node    *head;
        Node    *p;
        int     i;

        srand( time(0) );   // 初始化随机数种子 

        head = (Node *)malloc( sizeof(Node) );
        head->Next = NULL;

        for( i=0; i<num; i++ )
        {
            p = (Node *)malloc( sizeof(Node) ); // 新结点
            p->data = rand()%100+1;
            p->Next = head->Next;
            head->Next = p; 
        }
        return head;
}

int get_mid_node( Node *head, int *e )
{
    Node   *search;
    Node   *mid;
    mid = search = head;

    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;
}


int main()
{
    Node     *L ;
    Node     *p ;
    int      *num;
    int      a;

    num = NULL;

    L = create_list_head(20);

    p = (Node *)malloc( sizeof(Node) ); // 新结点
    p = L->Next;

    while( p != NULL)
    {
        printf("%d\n",p->data);
        p = p->Next;
    }

    
    get_mid_node( L, &a );
    printf("The mid data is %d\n", a);
    
    return 0;
}

在这里插入图片描述

写代码遇到的问题:

  1. 结点的问题
    我在定义结点结构体的时候,犯了很大的错误,我把Next定成了Node *类型,这样是不行的,我Node是在结构体外面定义的,在结构体里面不能用。所以只能用一开始结构体的名字定义它的类型,应该定义为 struct _Node *Next;

  2. 类型匹配的问题
    比如我定义的a是int类型的,而在get_mid_node( Node *head, int *e )函数里面,e的类型是int * 类型的,所以要类型一致,a是一个值,而指针指向的是地址,所以要写成&a当做形参。最后调用的时候写成get_mid_node( L, &a )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值