数据结构的练习day1

这篇具有很好参考价值的文章主要介绍了数据结构的练习day1。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数据结构的练习day1

链表只能一个一个的遍历,不能通过随机访问来获取节点

数据结构的练习day1

链表的地址是并要求连续的,是通过内部的指针来进行联系的

数据结构的练习day1

/********************************************************************************************************
 *
 *
 *
 *
 *
 *
 * Copyright (c)  2023-2024   2556560122@qq.com    All right Reserved
 * ******************************************************************************************************/

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

// 指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int DataType_t;

// 构造链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct LinkedList
{
  DataType_t data;         // 结点的数据域
  struct LinkedList *next; // 结点的指针域

} LList_t;

// 创建一个空链表,空链表应该有一个头结点,对链表进行初始化
LList_t *LList_Create(void)
{
  // 1.创建一个头结点并对头结点申请内存
  LList_t *Head = (LList_t *)calloc(1, sizeof(LList_t));
  if (NULL == Head)
  {
    perror("Calloc memory for Head is Failed");
    exit(-1);
  }

  // 2.对头结点进行初始化,头结点是不存储有效内容的!!!
  Head->next = NULL;

  // 3.把头结点的地址返回即可
  return Head;
}

// 创建新的结点,并对新结点进行初始化(数据域 + 指针域)
LList_t *LList_NewNode(DataType_t data)
{
  // 1.创建一个新结点并对新结点申请内存
  LList_t *New = (LList_t *)calloc(1, sizeof(LList_t));
  if (NULL == New)
  {
    perror("Calloc memory for NewNode is Failed");
    return NULL;
  }

  // 2.对新结点的数据域和指针域进行初始化
  New->data = data;
  New->next = NULL;

  return New;
}

// 头插
bool LList_HeadInsert(LList_t *Head, DataType_t data)
{
  // 1.创建新的结点,并对新结点进行初始化
  LList_t *New = LList_NewNode(data);
  if (NULL == New)
  {
    printf("can not insert new node\n");
    return false;
  }

  // 2.判断链表是否为空,如果为空,则直接插入即可
  if (NULL == Head->next)
  {
    Head->next = New;
    return true;
  }

  // 3.如果链表为非空,则把新结点插入到链表的头部
  New->next = Head->next;
  Head->next = New;

  return true;
}

// 尾插
bool LList_TailInsert(LList_t *Head, DataType_t data)
{
  if (Head->next == NULL)
  {
    printf("链表尾空!\n");
    return false;
  }
  // 新建一个指针指向Head的next
  LList_t *copy_head = Head->next;
  // 创建一个新的节点
  LList_t *newNode = LList_NewNode(data);
  while (copy_head)
  {
    // 到了尾节点了
    if (copy_head->next == NULL)
    {
      // 尾插
      copy_head->next = newNode;
      // 退出循环
      break;
    }
    copy_head = copy_head->next;
  }
  return true;
}

// 插到目标节点的后面
bool LList_DestInsert(LList_t *Head, DataType_t dest, DataType_t data)
{
  if (Head->next == NULL)
  {
    printf("链表尾空!\n");
    return false;
  }
  // 新建一个指针指向Head的next
  LList_t *copy_head = Head->next;
  // 创建一个新的节点
  LList_t *newNode = LList_NewNode(data);
  while (copy_head)
  {
    // 找到了目标节点
    if (copy_head->data == dest)
    {
      // 指向目标节点的next
      newNode->next = copy_head->next;
      // 目标节点指向新节点
      copy_head->next = newNode;
      // 找到了,退出方法,放回true
      return true;
    }
    // 没找到,指针指向下个节点
    copy_head = copy_head->next;
  }
  // 没找到
  return false;
}

// 寻找链表的最小值
int Select_Min_Node(LList_t *Head)
{
  if (Head->next == NULL)
  {
    printf("链表尾空!\n");
    return -1;
  }
  // 新建一个指针指向Head的next
  LList_t *copy_head = Head->next;
  // 默认最小值是copy_head的data
  int min = copy_head->data;
  while (copy_head->next)
  {
    // 如果min大于下个节点的数值,min就发生交换
    if (min > copy_head->next->data)
    {
      min = copy_head->next->data;
    }
    // 进入下个节点
    copy_head = copy_head->next;
  }
  return min;
}

// 删除最小数据的节点
void DelectMinDataNode(LList_t *Head)
{
  if (Head->next == NULL)
  {
    printf("链表为空!\n");
    return;
  }
  // 新建一个指针指向Head的next
  LList_t *copy_head = Head;
  // 获取链表中的最小数据
  int delVal = Select_Min_Node(Head);
  while (copy_head->next)
  {
    if (copy_head->next->data == delVal)
    {
      // 创建一个指针保存要删除的节点的next
      LList_t *copy_del_next = copy_head->next->next;
      // 释放空间
      free(copy_head->next);
      // 指向要删除的节点的next
      copy_head->next = copy_del_next;
      // 退出循环
      break;
    }
    copy_head = copy_head->next;
  }
  return;
}

// 遍历
void LList_Print(LList_t *Head)
{
  // 对链表的头文件的地址进行备份
  LList_t *Phead = Head;

  // 首结点
  while (Phead->next)
  {
    // 把头的直接后继作为新的头结点
    Phead = Phead->next;

    // 输出头结点的直接后继的数据域
    printf("data = %d\n", Phead->data);
  }
}

int main(int argc, char const *argv[])
{
  // 创建链表头节点
  LList_t *Head = LList_Create();
  // 头插
  LList_HeadInsert(Head, 0);
  LList_HeadInsert(Head, 5);
  LList_HeadInsert(Head, 20);
  LList_HeadInsert(Head, 1);
  // 尾插
  LList_TailInsert(Head, 20);
  // 在目标后面插
  LList_DestInsert(Head, 5, 2);
  // 删除链表中数据最小的节点
  DelectMinDataNode(Head);
  // 遍历链表
  LList_Print(Head);
  return 0;
}

数据结构的练习day1文章来源地址https://www.toymoban.com/news/detail-855664.html

/********************************************************************************************************
 *
 *查找链表的倒数第k个节点的数据
 *思想: 可以根据链表的节点数-k来获取需要head的next的次数来获取节点
 *
 *
 *
 * Copyright (c)  2023-2024   2556560122@qq.com   All right Reserved
 * ******************************************************************************************************/

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

// 指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
typedef int DataType_t;

// 构造链表的结点,链表中所有结点的数据类型应该是相同的
typedef struct LinkedList
{
  DataType_t data;         // 结点的数据域
  struct LinkedList *next; // 结点的指针域

} LList_t;

// 创建一个空链表,空链表应该有一个头结点,对链表进行初始化
LList_t *LList_Create(void)
{
  // 1.创建一个头结点并对头结点申请内存
  LList_t *Head = (LList_t *)calloc(1, sizeof(LList_t));
  if (NULL == Head)
  {
    perror("Calloc memory for Head is Failed");
    exit(-1);
  }

  // 2.对头结点进行初始化,头结点是不存储有效内容的!!!
  Head->next = NULL;

  // 3.把头结点的地址返回即可
  return Head;
}

// 创建新的结点,并对新结点进行初始化(数据域 + 指针域)
LList_t *LList_NewNode(DataType_t data)
{
  // 1.创建一个新结点并对新结点申请内存
  LList_t *New = (LList_t *)calloc(1, sizeof(LList_t));
  if (NULL == New)
  {
    perror("Calloc memory for NewNode is Failed");
    return NULL;
  }

  // 2.对新结点的数据域和指针域进行初始化
  New->data = data;
  New->next = NULL;

  return New;
}

// 头插
bool LList_HeadInsert(LList_t *Head, DataType_t data)
{
  // 1.创建新的结点,并对新结点进行初始化
  LList_t *New = LList_NewNode(data);
  if (NULL == New)
  {
    printf("can not insert new node\n");
    return false;
  }

  // 2.判断链表是否为空,如果为空,则直接插入即可
  if (NULL == Head->next)
  {
    Head->next = New;
    return true;
  }

  // 3.如果链表为非空,则把新结点插入到链表的头部
  New->next = Head->next;
  Head->next = New;

  return true;
}

// 遍历
void LList_Print(LList_t *Head)
{
  // 对链表的头文件的地址进行备份
  LList_t *Phead = Head;

  // 首结点
  while (Phead->next)
  {
    // 把头的直接后继作为新的头结点
    Phead = Phead->next;

    // 输出头结点的直接后继的数据域
    printf("data = %d\n", Phead->data);
  }
}
/********************************************************************************************************
 *
 * 查找链表中倒数第k个位置上的节点
 * ①先遍历链表记录链表的节点数
 * ②然后通过for循环链表来获取到链表中倒数第k个位置上的节点,并且返回其data
 * ③找到返回1,没找到返回0
 *
 *
 *
 * ******************************************************************************************************/
int SelectRecNode(LList_t *Head, DataType_t k)
{
  if (Head->next == NULL)
  {
    printf("链表为空!\n");
    return 0;
  }
  // 新建一个指针指向Head的next
  LList_t *copy_head = Head->next;
  // 记录其节点数
  int count = 0;
  // 通过while循环记录链表的节点数
  while (copy_head)
  {
    count++;
    copy_head = copy_head->next;
  }
  // 把copy_head重新指向Head的next
  copy_head = Head->next;
  // 通过节点数-k就是其节点在链表中的位置
  for (int i = 0; i < count - k; i++)
  {
    copy_head = copy_head->next;
  }
  printf("链表中倒数第%d个节点的数值是%d\n", k, copy_head->data);
  return 1;
}

int main()
{
  // 创建链表头节点
  LList_t *Head = LList_Create();
  // 头插
  LList_HeadInsert(Head, 1);
  LList_HeadInsert(Head, 2);
  LList_HeadInsert(Head, 3);
  LList_HeadInsert(Head, 4);
  LList_HeadInsert(Head, 5);
  LList_HeadInsert(Head, 6);
  LList_Print(Head);
  SelectRecNode(Head, 3);
}

到了这里,关于数据结构的练习day1的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法学习(day1)——简化版桶排序

    (1)我是一个大三的学生(准确来说应该是准大三,因为明天才报名哈哈哈)。 (2)最近就想每天闲着没事也刷些C语言习题来锻炼下编程水平,也一直在思考企业对应届大学生能力的要求,所以经常会想到关于面试的事情。由于我也没实习过,所以我对面试没有一个具象化

    2024年02月09日
    浏览(42)
  • <数据结构> 链表 - 小练习

    线性表在 ▁▁▁▁ 情况下适合采用链式存储结构。 A.线性表中数据元素的值需经常修改 B.线性表需经常插入或删除数据元素 C.线性表包含大量的数据元素 D.线性表的数据元素包含大量的数据项 链表要求内存中可用存储单元的地址 ▁▁▁▁▁ 。 A.必须是连续的 B.部分地址必

    2023年04月08日
    浏览(27)
  • 【数据结构(四)】链表经典练习题

    ❣博主主页: 33的博客❣ ▶️文章专栏分类:数据结构◀️ 🚚我的代码仓库: 33的代码仓库🚚 🫵🫵🫵 关注我带你学更多数据结构知识 在上一篇文章中博主已经介绍了链表的基础知识,什么是链表,如何实现一个链表,以及LinkedList的操作方法,那么在这篇文章中通过一些链

    2024年04月22日
    浏览(45)
  • 数据结构之链表练习与习题详细解析

    个人主页:点我进入主页 专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶 C语言刷题       数据结构初阶 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2.习题解析 2.1习题一 2.2习题二 2.3习题三 2.4习题四 2.

    2024年02月05日
    浏览(43)
  • 18.5:给定一个栈,请逆序这个栈,不能申请额外的数据结构,只能使用递归函数

    假设我们有一个f方法:可以拿到栈底元素,并保证其他元素栈中顺序不变。 上来就调用f方法,拿到栈底元素 lowValue 。此时stack中栈底元素被拿走了。 这个递归不断的调用f方法,直到栈为空。即:在递的过程中,将栈底元素都收集好了,并且顺序由前往后正好是倒序。 然后

    2024年02月11日
    浏览(40)
  • 数据结构的练习day2(未完待续)

    数据结构线性结构之单向循环链表的基本操作

    2024年04月24日
    浏览(35)
  • 趣说数据结构(练习2) —— 顺序表/链表力扣刷题(中等难度)

    力扣原题:https://leetcode.cn/problems/reverse-linked-list-ii/ 题目描述 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left = right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 示例 1 输入:head = [1,2,3,4,5], left = 2, right = 4 输出:[1,4,3,2,5] 示例 2 输入:h

    2024年02月01日
    浏览(45)
  • 数据结构day06(单向循环链表、双向链表)

    双向链表的练习代码 head.h fun.c main.c 今日思维导图哈 ​​​​​​​

    2024年02月10日
    浏览(35)
  • 数据结构:链表基础OJ练习+带头双向循环链表的实现

    目录 一.leetcode剑指 Offer II 027. 回文链表 1.问题描述 2.问题分析与求解 (1) 快慢指针法定位链表的中间节点 (2) 将链表后半部分进行反转 附:递归法反转链表 (3) 双指针法判断链表是否回文 二.带头双向循环链表的实现 1.头文件 2.节点内存申请接口和链表初始化接口 3.链表的打

    2024年02月02日
    浏览(49)
  • 新星计划Day6【数据结构与算法】 链表Part2

    👩‍💻博客主页:京与旧铺的博客主页 ✨欢迎关注🖱点赞🎀收藏⭐留言✒ 🔮本文由京与旧铺原创,csdn首发! 😘系列专栏:java学习 💻首发时间:🎞2022年4月30日🎠 🎨你做三四月的事,八九月就会有答案,一起加油吧 🀄如果觉得博主的文章还不错的话,请三连支持一

    2023年04月08日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包