重排链表(C语言)

简介: 这题我们将使用栈解决这个问题,利用栈先进后出的特点,从链表的中间位置进行入栈,寻找链表的中间位置参考:删除链表的中间节点,之后从头开始进行连接。

c0439ae178b34c69a48362bbff1c5a56.png


题目:

35f85c065b4348be8ded431f850bf51b.png

示例:

76dcc3a08e6d400fb9ce8b3889226dd9.png

b81ef1eeca784a3fbb77994ed8981bc5.png


思路:

这题我们将使用栈解决这个问题,利用栈先进后出的特点,从链表的中间位置进行入栈,寻找链表的中间位置参考:删除链表的中间节点,之后从头开始进行连接。


本题使用的栈源代码在此处:栈和队列的实现


图示:

c59ecbe411e14fa7b91b8b969314f45a.png

6ac2cbc6b1a54819993daaf19f67b4fb.png



代码:

//栈
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef struct ListNode* DataType;
typedef struct Stack
{
  DataType* data;
  int top;
  int capacity;
}Stack;
void Init(Stack *st);
void Push(Stack* st, DataType x);
void Pop(Stack* st);
DataType GetTop(Stack* st);
bool Empty(Stack* st);
void Init(Stack* st)
{
  assert(st);
  st->data = NULL;
  st->top = 0;
  st->capacity = 0;
}
void Push(Stack* st, DataType x)
{
  assert(st);
  if (st->capacity == st->top)
  {
    int newcapacity = (st->capacity == 0) ? 4 : st->capacity * 2;
    DataType* temp = (DataType*)realloc(st->data, sizeof(DataType) * newcapacity);
    if (temp == NULL)
    {
      perror("realloc fail");
      exit(-1);
    }
    st->data = temp;
    st->capacity = newcapacity;
  }
  st->data[st->top++] = x;
}
void Pop(Stack* st)
{
  assert(st);
  assert(st->top > 0);
  st->top--;
}
DataType GetTop(Stack* st)
{
  assert(st);
  assert(st->top > 0);
  return st->data[st->top - 1];
}
bool Empty(Stack* st)
{
  assert(st);
  return (st->top == 0);
}
//寻找链表的中间位置
struct ListNode* findMiddle(struct ListNode* head)
{
    if(head == NULL || head->next == NULL)
        return NULL;
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}
//于此处开始正式解题
void reorderList(struct ListNode* head)
{
    if(head == NULL || head->next == NULL)
        return head;
    Stack list;
    Init(&list);
    struct ListNode* middle = findMiddle(head);
    while(middle)
    {
        Push(&list,middle);
        middle = middle->next;
    }
    struct ListNode* cur = head;
    struct ListNode* next = NULL;
    int flag = 1;
    while(!Empty(&list))
    {
        if(flag == 1)
        {
            next = cur->next;
            cur->next = GetTop(&list);
            Pop(&list);
            flag = 0;
        }
        else
        {
            cur->next = next;
            flag = 1;
        }
        cur = cur->next;
    }
    cur->next = NULL;
    return head;
}


目录
相关文章
|
6月前
|
C语言
对链表使用插入排序的C语言实现示例
对链表使用插入排序的C语言实现示例
|
6月前
|
C语言
基于链表实现的链式管理系统(C语言课设)
基于链表实现的链式管理系统(C语言课设)
|
16天前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
44 4
|
16天前
|
C语言
【数据结构】双向带头循环链表(c语言)(附源码)
本文介绍了双向带头循环链表的概念和实现。双向带头循环链表具有三个关键点:双向、带头和循环。与单链表相比,它的头插、尾插、头删、尾删等操作的时间复杂度均为O(1),提高了运行效率。文章详细讲解了链表的结构定义、方法声明和实现,包括创建新节点、初始化、打印、判断是否为空、插入和删除节点等操作。最后提供了完整的代码示例。
37 0
|
1月前
|
C语言
无头链表再封装方式实现 (C语言描述)
如何在C语言中实现无头链表的再封装,包括创建节点和链表、插入和删除操作、查找和打印链表以及销毁链表的函数。
26 0
|
1月前
|
测试技术 C语言
单链表之无头链表(C语言版)
本文详细介绍了使用C语言实现无头单链表的方法,包括节点和链表结构的定义、链表的创建与销毁、节点的插入与删除,以及链表的打印等功能。文章通过具体的代码示例,展示了如何在无头链表中进行头插法、尾插法、自定义位置插入和删除,以及如何清空和销毁链表。
28 0
单链表之无头链表(C语言版)
|
1月前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
22 0
|
4月前
|
存储 数据管理 C语言
C语言实战 | 使用链表完成“贪吃蛇”游戏
【7月更文挑战第1天】整体思维,即系统思维,强调以整体视角理解事物。在编程中,结构体体现这种思想,将相关变量打包处理。示例展示了如何用链表而非数组实现“贪吃蛇”游戏,链表提供了更灵活的动态数据管理。一系列代码图片详细描绘了链表结构体在游戏中的应用,包括节点定义、移动、碰撞检测等,凸显了使用链表的优势和代码的清晰组织。
44 0
C语言实战 | 使用链表完成“贪吃蛇”游戏
|
5月前
|
存储
数据结构——双向链表(C语言版)
数据结构——双向链表(C语言版)
31 2
|
5月前
|
算法 C语言
数据结构——单向链表(C语言版)
数据结构——单向链表(C语言版)
45 2