C语言单链表的实现及其面试题—完整代码

相关博客链接:

C语言实现 单向链表
https://blog.youkuaiyun.com/qq_37941471/article/details/72961495
C语言实现单链表面试题—基础篇
https://blog.youkuaiyun.com/qq_37941471/article/details/78033970
C语言实现单链表面试题—进阶
https://blog.youkuaiyun.com/qq_37941471/article/details/80437143


代码:

List.h List.c test.c
  • List.h :
#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <windows.h>
#include <assert.h>

typedef int DataType;
typedef struct ListNode
{
    DataType data;//节点存放的数据
    struct ListNode* next;//下一个节点
}ListNode;


ListNode* BuyNode(DataType x);//创建节点
void PrintList(ListNode *plist);//打印链表

void PushBack(ListNode **pplist,DataType x);//尾插
void PopBack(ListNode **pplist);//尾删

void PushFront(ListNode **pplist,DataType x);//头插
void PopFront(ListNode **pplist);//头删

ListNode* Find(ListNode *plist,DataType x);//查找x

void Insert(ListNode **pplist,ListNode* pos,DataType x);//在pos位置前面插入节点
void Erase(ListNode **pplist,ListNode *pos);//删除pos节点

void PrintTailToHead(ListNode *plist);//2.从尾到头打印单链表 
void EraseNonTail(ListNode* pos);//3.删除一个无头单链表的非尾节点 
void InsertNonHead(ListNode* pos,DataType x);//4.在无头单链表的一个节点前插入一个节点 
ListNode* JosepRing(ListNode* list,DataType k);//5.单链表实现约瑟夫环
void Reverse(ListNode** pplist);//6.翻转/逆置链表
void SortList(ListNode* list);//7.单链表排序(冒泡排序)
ListNode* Merge(ListNode* list1,ListNode* list2);//8.合并两个有序单链表,合并后依然有序
ListNode* FindMidNode(ListNode* plist);//9.查找链表的中间节点,要求只能遍历一次
void FindKNode(ListNode* plist,int k);//10.查找单链表的倒数第k个节点,要求只能遍历一次

ListNode* IsCycle(ListNode* plist);//11.判断链表是否带环?
ListNode* GetEntry(ListNode* plist, ListNode* MeetNode);//若带环,求其入口点
int GetCycle_Length(ListNode* MeetNode);//若带环,求环的长度

int IsCross_NoCycle(ListNode* plist1,ListNode* plist2);//12.判断两个链表是否相交?(假设链表不带环)
ListNode* GetCrossNode(ListNode* plist1, ListNode* plist2);//若相交,求交点

ListNode* IsCross_Cycle(ListNode* plist1,ListNode* plist2);//13.判断两个链表是否相交?若相交,求交点。(假设链表可能带环)


  • List.c :
#include "List.h"

ListNode* BuyNode(DataType x)//创建节点
{
    ListNode* Node = (ListNode*)malloc(sizeof(ListNode));//开辟空间
    Node->data = x;
    Node->next = NULL;
    return Node;
}

void PrintList(ListNode *plist)//打印链表
{
    ListNode* cur = plist;
    while (cur)
    {
        printf("%d->",cur->data);
        cur = cur->next ;
    }
    printf("NULL\n");
}

void PushBack(ListNode **pplist,DataType x)//尾插
{
    assert(pplist);
    //1. 链表为空
    //2. 一个节点
    //3. 多个节点

    if( *pplist == NULL )
    {
        *pplist = BuyNode(x);
    }
    else if( (*pplist)->next == NULL )
    {
        (*pplist)->next = BuyNode(x);
    }
    else //多节点
    {
        ListNode* cur = *pplist;
        while ( cur->next ) //终止条件(找最后一个节点):cur->next == NULL;所以继续条件恰好相反
        {
            cur = cur->next ;
        }
        cur->next = BuyNode(x);
    }
}

void PopBack(ListNode **pplist)//尾删
{
    assert(pplist);
    //1. 链表为空
    //2. 一个节点
    //3. 多个节点
    if( *pplist == NULL )
        return;
    else if( (*pplist)->next == NULL )
    {
        free(*pplist);//malloc free()
        *pplist = NULL;
    }
    else//多节点
    {
        ListNode* prev = *pplist;
        ListNode* cur = *pplist;
        while( cur->next )
        {
            prev = cur;
            cur = cur->next ;
        }
        free(cur);
        cur = NULL;
        prev->next = NULL;
    }
}

void PushFront(ListNode **pplist,DataType x)//头插
{
    assert(pplist);
    //1. 链表为空
    //2. 非空
    if( *pplist == NULL )
    {
        *pplist = BuyNode(x);
    }
    else //非空 
    {
        ListNode* Node = BuyNode(x);
        Node->next = *pplist;
        *pplist = Node;
    }
}

void PopFront(ListNode **pplist)//头删
{
    assert(pplist);
    //1. 链表为空
    //2. 一个节点
    //3. 多节点
    if( *pplist == NULL )
        return;
    else if ( (*pplist)->next == NULL )
    {
        free(*pplist);
        *pplist = NULL;
    }
    else//多节点
    {
        ListNode* tmp  = *pplist;
        ListNode* Next = (*pplist)->next ;
        *pplist = Next;
        free(tmp);
    }
}

ListNode* Find(ListNode *plist,DataType x)//查找x
{
    assert(plist);
    while( plist )
    {
        if( plist->data == x )
            return plist;
        plist = plist->next ;
    }
    return NULL;
}

void Insert(ListNode
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值