首页 > 其他分享 >单向链表的学习

单向链表的学习

时间:2024-04-25 21:23:49浏览次数:28  
标签:学习 结点 单向 Head Next 链表 LList Phead

单向链表的学习

链表:链式存储的线性表。

单向链表的优缺点

  • 优点
    1. 插入、删除时只需要调整几个指针,无需移动任何数据
    2. 当数据节点数量较多时,无需一整片较大的连续内存空间,可以灵活利用离散的内存
    3. 当数据节点数量变化剧烈时,内存的释放和分配灵活,速度快
  • 缺点
    1. 在节点中,需要多余的指针来记录节点之间的关联。
    2. 所有数据都是随机存储的,不支持立即访问任意一个随机数据。

习题练习

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


/*****************************************************
  * @function_name  : LList_DelMin
  * @brief_         : 删除单向链表中的最小值结点
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * 
  * @retval_        : 空
  * @date_          : 2024/04/22
  * @version_       : v1.1     
  * @note_          : None
  *******************************************************/

void LList_DelMin (LList_t *Head)
{ 
    LList_t *min_prev;    //记录最小值结点的前驱结点
    LList_t *min= Head->Next;               //记录最小值结点

    LList_t *phead=Head->Next;  //记录当前结点的地址
    LList_t *pnead_prev=Head;   //记录当前结点的前驱结点的地址

    //1.遍历链表找到最小值结点
    while(phead->Next)
    {
        //比较链表中的结点,找到最小值结点
        if(phead->Data < min->Data)
        {
            min = phead; 
            min_prev = pnead_prev;
        }
        //更新当前结点的前驱结点的地址
        pnead_prev = phead;
        phead = phead->Next;
    }
    //2.删除最小值结点
    min_prev->Next = min->Next;
    min->Next = NULL;
    free(min);
    return;
}

查找单向链表中倒数第K个结点的数据并输出

/*****************************************************
  * @function_name  : OutLast
  * @brief_         : 查找链表倒数第K个结点输出data值
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  *                   int k         --> 倒数第k个结点
  * @retval_        : 空
  * @date_          : 2024/04/22
  * @version_       : v1.1     
  * @note_          : None
  *******************************************************/

//查找倒数第k个结点,查找成功输出data值,并返回1,输出不成功 返回0
int OutLastK(LList_t *Head,int k)
{
    //1.判断链表是否为空,如果为空,直接返回
    if(Head->Next == NULL)
    {
        return 0;
    }
    //2.遍历链表找到要删除的结点
    LList_t *Tel = Head;   //移动节点 判断结束
    LList_t *Mel = Head;   //记录倒数第k个结点
    //移动节点先移动k-1个节点
    for (int i = 0; i < k-1; i++)
    {
        Tel = Tel->Next; 
        if(Tel->Next == NULL)
        return 0;               
    }

    while(Tel->Next != NULL)
    {
        Tel = Tel->Next;
        Mel = Mel->Next;
    }
    printf("data=%d\n",Mel->Data);
    return 1;
}

单向链表的增删改查实现

初始化单向链表

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

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

//创建一个空链表,空链表应该有一个头结点,对链表进行初始化
LList_t *CreateEmptyLinkedList(void)
{
	//1.创建一个头结点并为头结点申请内存
        LList_t *Head = (LList_t *)calloc(1,sizeof(LList_t));
        if(Head == NULL)
        {
            perror("Calloc memory for Head is Failed");
            return NULL;
        }
	//2.对头结点进行初始化,头节点是不存储有效内容的
    Head->Next = NULL;

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

//创建新的结点,并对新结点进行初始化(数据域+指针域)
LList_t *CreateNewLinkedList(DataType_t Data)
{
    //1.申请一个结点的内存空间
    LList_t *NewNode = (LList_t *)calloc(1,sizeof(LList_t));
    if(NewNode == NULL)
    {
        perror("Calloc memory for Head is Failed");
         exit(-1);
    }
    //2.对新结点的数据域和指针域进行初始化
    NewNode->Data = Data;
    NewNode->Next = NULL;
    //3.返回新结点的地址
    return NewNode;
}

插入结点

头插

/*****************************************************
  * @function_name  : InsertLinkedList
  * @brief_         : 将新结点插入链表中的头结点的Next
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 新结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//头插
bool InsertLinkedList(LList_t *Head,DataType_t Data)
{
    //1.创建一个新结点
    LList_t *NewNode = CreateNewLinkedList(Data);
    if(NewNode == NULL)
    {
        perror("Calloc memory for Head is Failed");
        return false;
    }
    //2.判断链表是否为空,如果为空,则新结点直接插入到链表的头部
    if(Head->Next == NULL)
    {
        Head->Next = NewNode;
        return true;
    }
    //3.如果链表不为空,则新结点插入到链表的头部
    NewNode->Next = Head->Next;
    Head->Next = NewNode;
    return true;
}

尾插

/*****************************************************
  * @function_name  : InsertTailLinkedList
  * @brief_         : 将新结点插入链表中的尾结点的Next
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 新结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//尾插
bool InsertTailLinkedList(LList_t *Head,DataType_t Data)
{
    //1.创建一个新结点
    LList_t *NewNode = CreateNewLinkedList(Data);
    if(NewNode == NULL)
    {
        perror("Calloc memory for Head is Failed");
        return false;
    }
    
    //2.判断链表是否为空,如果为空,则新结点直接插入到链表的尾部
    if(Head->Next == NULL)
    {
        Head->Next = NewNode;
        return true;
    }
    //3.如果链表不为空,则新结点插入到链表的尾部
    LList_t *Tail = Head->Next;
    while(Tail->Next != NULL)
    {       
        Tail = Tail->Next;
    }
        Tail->Next = NewNode;
        return true;
    }

指定插

/*****************************************************
  * @function_name  : InsertDestProList
  * @brief_         : 指定结点数据域,将新结点插到目标结点的Next
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 新结点的有效数据
  *                   DataType_t dest --> 目标结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/

//找到目标值插入
bool InsertDestProList(LList_t *Head,DataType_t dest,DataType_t Data)
{
    
    //1.创建一个新结点
    LList_t *New = CreateNewLinkedList(Data);
    if(New == NULL)
    {
        perror("Calloc memory for Head is Failed");
        return false;
    }
    
    //2.判断链表是否为空,如果为空,输出错误信息
    if(Head->Next == NULL)
    {
        perror("InsertDestList is Failed");
        return true;
    }
    
	LList_t *Phead = Head->Next;//备份首节点的地址
    
    //3.遍历, 先找到目标结点
    while(NULL != Phead && dest != Phead->Data)
    //查找data值为dest的结点
    {
        Phead = Phead->Next;//把头的直接后继作为新的头结点
    }
    
    //4.若目标结点不存在
    if (NULL == Phead) 
        return false;//不存在元素为dest的结点, 返回false

    //5.若目标结点存在且只存在一个结点
    if (NULL == Phead->Next)
    {
        Phead->Next = New;//让头结点链接新结点
        return true;
    }
	//6.若目标结点存在且存在多个结点
    else
    {   New->Next = Phead->Next;//新结点先链接后面的结点
		Phead->Next = New;//让目标元素结点链接新结点
		return true;
    }
}

删除结点

头删

/*****************************************************
  * @function_name  : DeleteHeadLinkedList
  * @brief_         : 将链表的首结点删除
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//头删
bool DeleteHeadLinkedList(LList_t *Head)
{
    //1.判断链表是否为空,如果为空,直接返回
    if(Head->Next == NULL)
    {
        return false;
    }
    //2.判断链表是否只有一个结点,如果只有一个结点,则直接删除该结点
    if(Head->Next->Next == NULL)
    {
        free(Head->Next);
        Head->Next = NULL;
        return true;
    }
    //3.如果链表有多个结点,则删除第一个结点
    LList_t *Phead = Head->Next;
    Head->Next = Phead->Next;
    Phead->Next = NULL;
}

尾删

/*****************************************************
  * @function_name  : DeleteTailLinkedList
  * @brief_         : 将链表的尾结点删除
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//尾删
bool DeleteTailLinkedList(LList_t *Head)
{
    //1.判断链表是否为空,如果为空,直接返回
    if(Head->Next == NULL)
    {
        return false;
    }
    //2.判断链表是否只有一个结点,如果只有一个结点,则直接删除该结点
    if(Head->Next->Next == NULL)
    {
        free(Head->Next);
        Head->Next = NULL;
        return true;
    }
    //3.如果链表有多个结点,则删除最后一个结点
    LList_t *Del= Head;
    LList_t *Phead = Head->Next;
    while(Del->Next != NULL)
    {
        Del = Del->Next;
        Phead = Phead->Next;
    }
    Del->Next = NULL;
    free(Phead);
    return true;
}

指定删

/*****************************************************
  * @function_name  : DeleteLinkedList
  * @brief_         : 指定结点数据域,将目标结点删除(只删除第一个目标结点)
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 目标结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//删除链表中的结点
bool DeleteLinkedList(LList_t *Head,DataType_t Data)
{
    //1.判断链表是否为空,如果为空,直接返回
    if(Head->Next == NULL)
    {
        return false;
    }
    //2.遍历链表找到要删除的结点
    LList_t *Tel = Head;
    LList_t *Del = Head->Next;
    while(Del -> Data != Data )
    {
        Del = Del->Next;
        Tel = Tel->Next;
    }
    //3.如果只有一个首元结点且该结点需要删除
    if(Del->Data == Data && Del->Next == NULL)
    {
        Head->Next = Del->Next;
        free(Del);
        return true;
    }

    //4.如果删除结点在中间,则删除该结点 
    if(Del->Data == Data && Del->Next != NULL)
    {  
        LList_t *Tmp = Del -> Next;
        Del->Data = Tmp->Data;
        Del->Next = Tmp->Next;
        Tmp->Next = NULL;  //释放内存,防止内存泄漏
        free(Tmp);
        return true;
    }

    //5.如果删除结点是尾结点,则删除该结点
    if(Del->Data == Data && Del->Next == NULL)
    {
        Tel->Next = NULL;
        free(Del);
        return true;
    }
    //6.如果没找到要删除的结点,则直接返回   
    perror("Delete LinkedList is Failed");
    return true;
}

遍历链表

/*****************************************************
  * @function_name  : PrintLinkedList
  * @brief_         : 将链表的数据域输出打印
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/   
//遍历链表
bool PrintLinkedList(LList_t *Head)
{
    //1.判断链表是否为空,如果为空,直接返回
    if(Head->Next == NULL)
    {
        printf("LinkedList is Empty\n");
        return false;
    }
   //对链表头文件的地址进行备份
   LList_t *Phead = Head;
   //遍历链表
   while(Phead -> Next)
   {
    //把头的直接后继作为新的头结点
    Phead = Phead->Next;
    //打印有效数据
    printf("data=%d\n",Phead->Data);
   }
   return true;
}

摧毁链表

/*****************************************************
  * @function_name  : DestroyLinkedList
  * @brief_         : 摧毁链表,释放空间
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * @retval_        : 空
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/

 //摧毁单向链表
 void DestroyLinkedList(LList_t *Head)
 {
     //1.判断链表是否为空,如果为空,直接返回
     if(Head->Next == NULL)
     {
         return;
     }
     //2.遍历单向链表找到要删除的结点
     LList_t *Tel = Head;
     LList_t *Del = Head->Next;
     while(Del != NULL)
     {
         Tel = Del;
         Del = Del->Next;
         Tel->Next = NULL;
         free(Tel);
     }
     //3.释放链表头结点的地址
     Head->Next = NULL;
     free(Head);
     return;
 }

单向循环链表的增删改查实现

初始化单向循环链表

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

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

//创建一个空链表,空链表应该有一个头结点,对链表进行初始化
LList_t *CreateEmptyLinkedList(void)
{
	//1.创建一个头结点并为头结点申请内存
        LList_t *Head = (LList_t *)calloc(1,sizeof(LList_t));
        if(Head == NULL)
        {
            perror("Calloc memory for Head is Failed");
            return NULL;
        }
	//2.对头结点进行初始化,头节点是不存储有效内容的
    Head->Next = NULL;

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

//创建新的结点,并对新结点进行初始化(数据域+指针域)
LList_t *CreateNewLinkedList(DataType_t Data)
{
    //1.申请一个结点的内存空间
    LList_t *NewNode = (LList_t *)calloc(1,sizeof(LList_t));
    if(NewNode == NULL)
    {
        perror("Calloc memory for Head is Failed");
         exit(-1);
    }
    //2.对新结点的数据域和指针域进行初始化
    NewNode->Data = Data;
    NewNode->Next = NULL;
    //3.返回新结点的地址
    return NewNode;
}

插入结点

头插

/*****************************************************
  * @function_name  : InsertCList
  * @brief_         : 将新结点插入链表中的头结点的Next
  * @param_         : 
  *                   CList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 新结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//头插
bool InsertCList(CList_t *Head, DataType_t Data)
{
    //1.创建一个新结点,并对新结点进行初始化
    CList_t *new = CreateNewCLinkedList(Data);
    //2.判断当前链表是否为空,为空则插入头结点之后
    if (Head->Next == Head)
    {
        Head->Next = new;
        new->Next = new;
    }
    else   //链表非空,需要对尾结点的Next指针指向新的首结点
    {
        CList_t *Phead = Head->Next;
        while (Phead->Next != Head->Next)
        {
            Phead = Phead->Next;
        }

        new->Next = Head->Next; 
        Head->Next = new;   //头结点指向新结点
        Phead->Next = new;  //尾结点指向新结点
    }

    return true;
}

尾插

/*****************************************************
  * @function_name  : InsertTailCList
  * @brief_         : 将新结点插入链表中的尾结点的Next
  * @param_         : 
  *                   CList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 新结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/

//尾插
bool InsertTailCList(CList_t *Head, DataType_t Data)
{
    //1.创建新的结点,并对新结点进行初始化
    CList_t *new = CreateNewCLinkedList(Data);
    //2.判断当前链表是否为空,为空则插入头结点之后
    if (Head->Next == Head)
    {
        Head->Next = new;
        new->Next = new;
    }
    //3.如果链表非空,需要对旧尾结点的Next指针指向新的尾结点
    else
    {    
        CList_t *Phead = Head->Next;  //备份首结点地址
        while (Phead->Next != Head->Next)  //遍历链表,找到尾结点
        {
            Phead = Phead->Next;
        }
        
        Phead->Next = new;    //尾结点指向新结点
        new->Next = Head->Next;  //新结点的Next指针指向首结点
    }
    return true;
}

指定插

/*****************************************************
  * @function_name  : InsertPosCList
  * @brief_         : 指定结点数据域,将新结点插到目标结点的Next
  * @param_         : 
  *                   CList_t *Head --> 链表头结点的地址
  *                   DataType_t Data --> 新结点的有效数据
  *                   DataType_t Dest --> 目标结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.1 
  * @note_          : None
  *******************************************************/

//指定目标位置插入
bool InsertPosCList(CList_t *Head, DataType_t Data,DataType_t Dest)
{
    //如果是空链表
    if(Head->Next == Head)
    {
        return false;
    }
    //创建新结点
    CList_t *new = CreateNewCLinkedList(Data);
    //创建一个指针,指向头结点
    CList_t *Pre = Head;
    CList_t *Phead = Head->Next;
    
    //遍历链表,找到目标结点
    while(Phead->Next != Head->Next)
    {
        if(Phead->Data == Dest)
        {
            break;
        }
        Pre=Pre->Next;
        Phead = Phead->Next;
    }
    //如果目标结点存在且是第一个
    if(Phead->Data==Dest && Phead == Head->Next)
    {
        InsertCList(Head, Data);
    }
    //如果目标结点存在且不是第一个
    else if(Phead->Data == Dest && Phead != Head->Next)
    {
        new->Next = Phead;
        Pre->Next = new;
    }
    else
    {
     perror("not found dest");
    }
    return true; 
}

删除结点

头删

/*****************************************************
  * @function_name  : DeleteCList
  * @brief_         : 将链表的首结点删除
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * @retval_        : bool
  * @date_          : 2024/04/23
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//头部删除 
bool DeleteCList(CList_t *Head)
{
    if(Head->Next == Head)
    {
        return false;
    }
    CList_t *Phead = Head->Next;
    CList_t *Ptail = Head->Next;
    while(Ptail->Next != Head->Next)
    {
      Ptail = Ptail->Next;
    }
    //如果链表中只有一个结点
    if(Phead == Ptail)
    {
        Head->Next = Head;  //头结点的Next指针指向头结点,体现循环
        Phead->Next = NULL;  //首结点的Next指针指向NULL
        free(Phead);
        return true;
    }
    //如果链表中不止一个结点
    Ptail->Next = Head->Next->Next;  //让尾结点的Next指针指向首结点
    Head->Next= Head->Next->Next; //更新首结点,让头结点的Next指针指向首结点
    Phead->Next = NULL;  //让被删除的结点的Next指针指向NULL
    free(Phead);  //释放被删除的结点的内存空间
    return true;
}

尾删

/*****************************************************
  * @function_name  : DeleteTailCList
  * @brief_         : 将链表的尾结点删除
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
    *******************************************************/
    //尾部删除
    bool DeleteTailCList(CList_t *Head)
    {
    if(Head->Next == Head)
    {
        return false;
    }
    CList_t *Pre = Head;
    CList_t *Ptail = Head->Next;
    //遍历链表,找到尾结点
    while(Ptail->Next != Head->Next)
    {   
        Pre = Pre->Next;
        Ptail = Ptail->Next;
    }
    //如果链表中只有一个结点
    if(Pre == Ptail)
    {
        Head->Next = Head;
        Ptail->Next = NULL;
        free(Ptail);
        return true;
    }
    Pre->Next = Head->Next;
    Ptail->Next = NULL;
    free(Ptail);
    return true;
    }

指定删

/*****************************************************
  * @function_name  : DeletePosCList
  * @brief_         : 指定结点数据域,将目标结点删除(只删除第一个目标结点)
  * @param_         : 
  *                   LList_t *Head --> 链表头结点的地址
  *                   DataType_t Dest --> 目标结点的有效数据
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
//指定目标删除
bool DeletePosCList(CList_t *Head, DataType_t Dest)
{
    if(Head->Next == Head)
    {
        return false;
    }
    CList_t *Pre = Head;
    CList_t *Phead = Head->Next;
    while(Phead->Next != Head->Next)
    {
        if(Phead->Data == Dest)
        {
            break;
        }
        Phead = Phead->Next;
        Pre = Pre->Next;
    }
    //如果目标结点存在且是唯一一个
    if(Phead->Data == Dest && Phead == Phead->Next)
    {
        Head->Next = Head;
        Phead->Next = NULL;
        free(Phead);
        return true;
    }
    //如果目标结点存在且是第一个
    else if(Phead->Data == Dest && Pre == Head)
    {
        DeleteCList(Head);
        return true;
    }
    //如果目标结点存在且是最后一个
    else if(Phead->Data == Dest && Phead == Head->Next && Pre != Head)
    {
        DeleteTailCList(Head);
        return true;
    }
    //如果目标结点存在且不是第一个
    else if(Phead->Data == Dest && Phead != Head->Next)
    {
        Pre->Next = Phead->Next;
        Phead->Next = NULL;
        free(Phead);
        return true;
    }
    //目标结点不存在
    else
    {
        perror("not found dest");
    }

    return true;

}

遍历链表

/*****************************************************
  * @function_name  : CirCLList_Print
  * @brief_         : 将链表的数据域输出打印
  * @param_         : 
  *                   CList_t *Head --> 链表头结点的地址
  * @retval_        : bool
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/   
//遍历链表
bool CirCLList_Print(CList_t *Head)
{
	//对单向循环链表的头结点的地址进行备份
	CList_t *Phead = Head;
	
	//判断当前链表是否为空,为空则直接退出
	if (Head->Next == Head)
	{
		printf("current linkeflist is empty!\n");
		return false;
	}

	//从首结点开始遍历
	while(Phead->Next)
	{
		//把头结点的直接后继作为新的头结点
		Phead = Phead->Next;

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

		//判断是否到达尾结点,尾结点的next指针是指向首结点的地址
		if (Phead->Next == Head->Next)
		{
			break;
		}	
	}

	return true;
}

摧毁链表

/*****************************************************
  * @function_name  : DestroyLinkedList
  * @brief_         : 摧毁链表,释放空间
  * @param_         : 
  *                   CList_t *Head --> 链表头结点的地址
  * @retval_        : 空
  * @date_          : 2024/04/22
  * @version_       : v1.0 
  * @note_          : None
  *******************************************************/
  //摧毁链表,释放空间
  void DestroyLinkedList(CList_t *Head)
  {
    while(Head->Next != Head)
    {
        DeleteCList(Head);
    }
    Head->Next = NULL;
    free(Head);
  }

标签:学习,结点,单向,Head,Next,链表,LList,Phead
From: https://www.cnblogs.com/san39/p/18158616

相关文章

  • 双向链表的学习
    双向链表的学习经过单链表、双链表的学习,可以总结链表的适用场合:适合用于节点数目不固定,动态变化较大的场合适合用于节点需要频繁插入、删除的场合适合用于对节点查找效率不十分敏感的场合双向链表的增删改查实现双向链表的初始化//指的是双向链表中的节点有效数据......
  • 栈的学习
    栈的学习1.基本概念栈是一种逻辑结构,是特殊的线性表。特殊在:只能在固定的一端操作只要满足上述条件,那么这种特殊的线性表就会呈现一种“后进先出”的逻辑,这种逻辑就被称为栈。栈在生活中到处可见,比如堆叠的盘子、电梯中的人们、嵌套函数的参数等等。由于约定了只能在线性......
  • 双向循环链表的增删改查功能
    数据结构双向循环链表双向循环链表的增删改查/****************************************************************************************************************** * filename : DoubleCirLinkedList.c* author : [email protected]* data : 2024/04/24* funct......
  • 基于c语言数据结构-双循环链表
    DoubleCircularLinkedList双循环链表/**************************************************************函数名称:*函数功能:设计双向循环链表的接口*函数参数:*返回结果:*注意事项:None*函数作者:zcx982795194@[email protected]*创建日期:2024/04/25*修......
  • Web学习笔记(杂)
    理解React中的useStateHook在React中,useStatehook是一种用于在函数组件中添加状态的机制。通过useState,你可以在函数组件中声明状态变量,并且可以通过相应的函数来更新这些状态。例如:const[catHappiness,setCatHappiness]=useState(1);这段代码创建了一个名为cat......
  • 数据结构_链表_单向循环链表的初始化、插入、删除、修改、查询打印(基于C语言实现)
    版本:2024年4月25日V1.0发布于博客园/***@filename:CircularLinkedList.c*@brief:实现单向循环链表的相关功能*@author:[email protected]*@date:2024/04/25*@version:1.1*@note:*CopyRight(c)2023-2024RISE_A......
  • 数据结构——双向循环链表
    二、双向循环链表(一)双向循环链表的构造双向循环链表的首结点中的prev指针成员指向链表的尾结点,并且双向循环链表的尾结点里的next指针成员指向链表的首结点,所以双向循环链表也属于环形结构。1)构造双向循环链表的结点//双向链表中的结点有效数据类型,用户可以根据需要进行修......
  • 双向循环链表的插入和删除
    数据结构线性表--双向循环链表操作**注意!!!**怎么说,今天(2024.4.24)找一个小小的运行bug(没有报错)找了非常之久,明天继续把这些代码补齐,啊啊啊,但是感谢还是把这个bug找出来(这段话我不会删的)~~测试该程序的相关头文件和定义以及相关函数最后一个代码块。/****************......
  • 【笔记】动手学深度学习-预备知识
    预备知识2.1数据操作importtorchx=torch.arange(12)print(x.shape)print(torch.Size(x))print(x.numel())X=x.reshape(3,4)print(X)print(torch.ones((2,3,4)))print(torch.randn(3,4))print(torch.tensor([[2,1,3,4],[1,2,3,4],[3,4,5,......
  • JAVA安全学习 Day 1
    JAVAClassLoader机制谈起JAVA就不得不谈起他的基本类的加载机制谈一下我的粗略理解:我一开始也不理解为什么学习java安全要从一个classloader讲起,似乎有点太基层了,但是学到后面的cc链,才有了更明显的理解,因为只有深入理解了java的classloader机制才会在后面构造cc链的时候不会......