## 页首HTML代码 ```html

链表

数据结构

链表

题目预览:

1.设计一个算法删除单链表L(有头结点)中的一个最小值结点。

image

/**************************************************************************************
 *
 *
 *  file name:  demo_3.c
 *  author   :  Tongyaqi1110@163.com
 *  date     :  2024/04/22
 *  function :  设计一个算法,删除单链表最小值结点
 *  note     :  None
 *
 *  CopyRight (c)   2024    Tongyaqi1110@163.com   All Right Reserved
 *************************************************************************************/

#include <stdio.h>
/************************************************
*	
*	func name	:	 DeleteMin
*	function	:	插入一个元素后保持该顺序表仍然递增有序排列
*
*   argument	:	@LList_t *Head
*					
*	retval		:	DataType_t
*	note		:	None
*	author	 	:	tongyaqi1110@163.com
*	data  	 	:	2024/04/22
*
* ************************************************/
// 指的是单向链表中的结点有效数据类型,用户可以根据需要进行修改
#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;
}

// 先初始化三个指针变量
LList_t *q = NULL;
LList_t *h = NULL;
LList_t *p = NULL;
bool DeleteMin(LList_t *Head)
{
  //判空
  if (NULL == Head->next)
  {
    return false;
  }
  //三个指针都指向首结点
  q = Head->next;
  h = Head->next;
  p = Head;
  //遍历找到最小值结点
  //注意,循环中比较后h和q指向同一个位置
  do
  {
    if (h->data < q->next->data)
    {
      q = q->next;
    }
    else
    {

      h = q->next;
      q = q->next;
    }
  } while (q->next);
  // 遍历找出h的前驱
  while (p->next != h)
  {
    p = p->next;
  }
  //已经找到了最小节点h的前驱,前驱指向最小值结点的后面
  p->next = h->next;
  free(h);
}
// 遍历
void LList_Print(LList_t *Head)
{
  // 对链表的头文件的地址进行备份
  LList_t *Phead = Head;

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

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

int main(int argc, char const *argv[])
{
  LList_t *Head = LList_Create();
  LList_HeadInsert(Head, 1);
  LList_HeadInsert(Head, 5);
  LList_HeadInsert(Head, 7);
  LList_HeadInsert(Head, 4);
  LList_HeadInsert(Head, 3);
  LList_HeadInsert(Head, 6);
  LList_Print(Head);
  DeleteMin(Head);
  LList_Print(Head);
  return 0;
}
posted @ 2024-04-22 23:59  一面小镜子  阅读(21)  评论(0)    收藏  举报