链表面试题1

下面是对链表进行操作的前期准备工作—-创建一个链表

typedef int DataType;
typedef struct LinkList
{
    struct LinkList* next;
    DataType data;
}ListNode;
void InitLinkList(ListNode** pplist)//初始化
{
    assert(pplist);
    *pplist = NULL;
}

ListNode* BuyNode(DataType data)
{
    ListNode* pNewNode = (ListNode*)malloc(sizeof(ListNode));
    if (pNewNode == NULL)
    {
        perror("buy node::error");
        return NULL;
    }
    pNewNode->data = data;
    pNewNode->next = NULL;
    return pNewNode;
}


void PushBack(ListNode** pplist, DataType d)//后插
{
    assert(pplist != NULL);
    if (*pplist == NULL)
    {
        ListNode* newnode = BuyNode(d);
        if (newnode == NULL)
            return;
        *pplist = newnode;
    }
    else
    {
        ListNode* cur = *pplist;
        while (cur->next != NULL)
        {
            cur = cur->next;
        }
        cur->next = BuyNode(d);
    }
}
  • 从尾到头打印单链表
    思路:运用递归先找到最后一个节点,然后逆序打印
void PrintFromTailToFront(ListNode* pHead)//从尾到头打印单链表
{
    //assert(pHead);
    if (pHead)
    {
        PrintFromTailToFront(pHead->next);
        printf("%d ", pHead->data);
    }
}
  • 删除一个无头单链表的非尾节点(不能遍历链表)

思路:不动第一个节点,将第二个节点的值赋给第一个节点,让第一个节点的next指向第二个节点的next ,删除第二个节点,
知道链表只剩下一个节点

void DelectListNotTail(ListNode* pHead)//删除一个无头单链表的非尾节点
{
    ListNode* pDel = NULL;
    while (pHead && pHead->next)
    {
        pDel = pHead->next;
        pHead->data = pDel->data;
        pHead->next = pDel->next;
        free(pDel);
    }
}
  • 在无头单链表的一个节点前插入一个节点(不能遍历链表)

思路:先获取要插位置的节点信息,创建一个与要插位置节点data相同的节点,将新节点后插到指定的插入节点后面,然后将插入位置的节点值改为要插入节点的值,这样就完成了前插。

如图:要在3前面插入6

这是链表初试状态

这里写图片描述

创建节点,后插在3的后面

这里写图片描述

更改原始节点3的值为6
这里写图片描述

这样就完成了前插

代码:

ListNode* FindPosNode(ListNode* pHead, DataType pos)//找到指定节点的位置
{
    assert(pHead);
    while (pHead->data != pos)
    {
        pHead = pHead->next;
    }
    return pHead;
}

void InsertPosFront(ListNode* pos, DataType data)//在无头单链表的一个节点前插入一个节点(不能遍历链表)
{
    ListNode* NewNode = NULL;
    NewNode = BuyNode(pos->data);
    NewNode->next = pos->next;
    pos->next = NewNode;
    pos->data = data;
}
  • 单链表实现约瑟夫环
    思路:先创建一个环形链表,每次开始计数,当数到第m个节点时,将这个节点删除,删除的方法是将m的下一个节点的数据赋值给第m个节点,删除m的下一个节点(和上面的方法相似)
ListNode* LastNode(ListNode* pHead)//找最后一个节点
{
    //ListNode* Last;
    assert(pHead);
    while (pHead->next)
    {
        pHead = pHead->next;
    }
    return pHead;
}

ListNode* Last = LastNode(pHead);//找最后一个节点
Last->next = pHead;//单链表成环

ListNode* TosephCircle(ListNode* pHead,int m)//约瑟夫环
{
    int count = 0;
    ListNode* Del = NULL;
    while (pHead->next != pHead)
    {
        count = m;
        while (--count)
        {
            pHead = pHead->next;
        }
        Del = pHead->next;
        pHead->data = Del->data;
        pHead->next = Del->next;
        free(Del);
    }
    pHead->next = NULL;
    return pHead;
}
  • 逆置/反转单链表

思路:遍历链表,将链表节点通过头插的方式创建一个新的链表,最后将旧链表的头指针指向新链表(要传二级指针,这里要改变链表头指针的指向)

void ReverseList(ListNode** pHead)//逆置单链表
{
    ListNode* pNext = NULL;
    ListNode* pCur = NULL;
    ListNode* pNew = NULL;
    pCur = *pHead;
    while (pCur)
    {
        pNext = pCur->next;
        pCur->next = pNew;
        pNew = pCur;
        pCur = pNext;
    }
    *pHead = pNew;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值