学习记录day16—— 数据结构 双向链表 循环链表

news2024/9/24 11:24:53

双向链表

1、概念

        1)就是从任意一个节点既能存储其前驱节点,又能存储后继节点

        2)结构体中增加一个指向前驱节点的指针

//定义数据类型
typedef int datatype;
 
//定义节点类型
typedef struct Node
{
    union 
    {
        int len;
        datatype data;
    };
    struct Node *prio; 
    
    struct Node *next; 
    
};

        3)头节点没有前驱,最后一个节点没有后继

2、创建虚拟链表

// 创建链表
NodePtr list_create()
{
    // 在堆区申请一个头节点
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if (NULL == L)
    {
        printf("创建失败\n");
        return NULL;
    }

    L->len = 0;
    L->next = NULL;
    L->prio = NULL;

    printf("链表创建成功\n");
    return L;
}

3、申请封装数据

// 申请封装数据
NodePtr apply_node(datatype e)
{
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        printf("数据类型不合法,封装失败\n");
        return NULL;
    }

    p->data = e;
    p->prio = NULL;
    p->next = NULL;

    return p;
}

4、判空

// 判空
int list_empty(NodePtr L)
{
    return L->next == NULL;
}

5、头插

// 头插
int list_insert_head(NodePtr L, datatype e)
{
    if (NULL == L)
    {
        printf("数据类型不合法,头插失败\n");
        return -1;
    }

    NodePtr p = apply_node(e);
    if (NULL == p)
    {
        printf("数据封装失败,头插失败\n");
        return -1;
    }

    if (list_empty(L))
    {
        p->prio = L;
        L->next = p;
    }
    else
    {
        p->prio = L;
        p->next =  L->next;

        L->next->prio = p; // p->next->prio =p;
        L->next = p;
    }

    L->len++;

    printf("插入成功\n");
    return 0;
}

6、链表遍历

// 链表遍历
int list_show(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("遍历失败\n");
        return -1;
    }

    NodePtr q = L->next; // 定义遍历指针从第一个节点出发
    while (q)
    {
        // 输出数据域
        printf("%c", q->data);

        q = q->next; // 指针指向下一数据域
    }
    putchar(10);
    printf("遍历结束\n");
}

7、按完整查找

// 按位置查找
NodePtr list_search_pos(NodePtr L,datatype pos)
{
    if (NULL == L || list_empty(L) || pos > L->len || pos < 0)
    {
        printf("查找失败\n");
        return NULL;
    }

    NodePtr q = L;

    for(int i = 0;i < pos ; i++)
    {
        q = q->next;
    }

    printf("查找成功\n");
    return q;
}

8、按位置删除

// 按位置删除
int list_delete_pos(NodePtr L,datatype pos)
{
    if (NULL == L || list_empty(L) || pos < 1 || pos > L->len)
    {
        printf("按位置删除失败\n");
        return -1;
    }

    NodePtr q = list_search_pos(L,pos);

    if (q->next == NULL)
    {
        q->prio->next = NULL;

    }
    else
    {
        // q->next->prio = q->prio;
        // q->next->prio->next = q->next;

        q->prio->next = q->next;
        q->next->prio = q->prio;
        

    }
    L->len--;
    free(q);
    q = NULL;

    printf("删除成功\n");
    return 0;
}

9、链表删除

// 链表删除
void list_destroy(NodePtr L)
{
    if (NULL == L )
    {
        printf("删除失败\n");
        return;
    }
    
    while (L->next/*!(list_empty(L))*/)
    {
        list_delete_pos(L,1);
    }
    
    if (L->next = NULL)
    {
        free(L);
        L->next = NULL;
    }
    
    printf("删除成功\n");
    return ;
}

10、完整代码

00.h

#ifndef day16_flag_h
#define day16_flag_h
#include <myhead.h>

typedef char datatype;

typedef struct Node
{
    union 
    {
        int len;
        datatype data;
    };

    struct Node *prio;
    struct Node *next;
    
}Node,*NodePtr;

NodePtr list_create();

int  list_empty(NodePtr L);

NodePtr apply_node(datatype e);

int  list_insert_head(NodePtr l,datatype e);

int list_show(NodePtr L);

int list_search(NodePtr L,datatype pos);

int list_delete_pos(NodePtr L,datatype e);

void list_destroy(NodePtr L);

#endif // day16_flag_h

00.c 

#include "00.h"
#define MAX 50

// 创建链表
NodePtr list_create()
{
    // 在堆区申请一个头节点
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if (NULL == L)
    {
        printf("创建失败\n");
        return NULL;
    }

    L->len = 0;
    L->next = NULL;
    L->prio = NULL;

    printf("链表创建成功\n");
    return L;
}

// 判空
int list_empty(NodePtr L)
{
    return L->next == NULL;
}

// 申请封装数据
NodePtr apply_node(datatype e)
{
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        printf("数据类型不合法,封装失败\n");
        return NULL;
    }

    p->data = e;
    p->prio = NULL;
    p->next = NULL;

    return p;
}

// 头插
int list_insert_head(NodePtr L, datatype e)
{
    if (NULL == L)
    {
        printf("数据类型不合法,头插失败\n");
        return -1;
    }

    NodePtr p = apply_node(e);
    if (NULL == p)
    {
        printf("数据封装失败,头插失败\n");
        return -1;
    }

    if (list_empty(L))
    {
        p->prio = L;
        L->next = p;
    }
    else
    {
        p->prio = L;
        p->next =  L->next;

        L->next->prio = p; // p->next->prio =p;
        L->next = p;
    }

    L->len++;

    printf("插入成功\n");
    return 0;
}


// 链表遍历
int list_show(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("遍历失败\n");
        return -1;
    }

    NodePtr q = L->next; // 定义遍历指针从第一个节点出发
    while (q)
    {
        // 输出数据域
        printf("%c", q->data);

        q = q->next; // 指针指向下一数据域
    }
    putchar(10);
    printf("遍历结束\n");
}

// 按位置查找
NodePtr list_search_pos(NodePtr L,datatype pos)
{
    if (NULL == L || list_empty(L) || pos > L->len || pos < 0)
    {
        printf("查找失败\n");
        return NULL;
    }

    NodePtr q = L;

    for(int i = 0;i < pos ; i++)
    {
        q = q->next;
    }

    printf("查找成功\n");
    return q;
}

// 按位置删除
int list_delete_pos(NodePtr L,datatype pos)
{
    if (NULL == L || list_empty(L) || pos < 1 || pos > L->len)
    {
        printf("按位置删除失败\n");
        return -1;
    }

    NodePtr q = list_search_pos(L,pos);

    if (q->next == NULL)
    {
        q->prio->next = NULL;

    }
    else
    {
        // q->next->prio = q->prio;
        // q->next->prio->next = q->next;

        q->prio->next = q->next;
        q->next->prio = q->prio;
        

    }
    L->len--;
    free(q);
    q = NULL;

    printf("删除成功\n");
    return 0;
}

// 链表删除
void list_destroy(NodePtr L)
{
    if (NULL == L )
    {
        printf("删除失败\n");
        return;
    }
    
    while (L->next/*!(list_empty(L))*/)
    {
        list_delete_pos(L,1);
    }
    
    if (L->next = NULL)
    {
        free(L);
        L->next = NULL;
    }
    
    printf("删除成功\n");
    return ;
}

00main.c

#include "00.h"

int main(int argc, char const *argv[])
{
    NodePtr L = list_create();
    if (NULL == L )
    {
        return -1;
    }
    
    list_insert_head(L,'H');
    list_show(L);
    list_insert_head(L,'e');
    list_show(L);
    list_insert_head(L,'l');
    list_show(L);
    list_insert_head(L,'l');
    list_show(L);
    list_insert_head(L,'o');
    list_show(L);

    list_delete_pos(L,1);
    list_show(L);
    list_delete_pos(L,2);
    list_show(L);
    list_delete_pos(L,L->len);
    list_show(L);

    list_destroy(L);
    list_show(L);
    return 0;
}

单向循环链表

1、概念

        1)循环链表,就是首尾相接的链表

        2)循环链表,就是首尾相接的链表

        3)双向循环链表:需要将最后一个阶段的指针域指向头结点,头结点的前驱指针指向最后一                 个阶段

2、循环链表的创建

        1)创建虚拟链表

// 创建链表
NodePtr list_create()
{
    // 在堆区申请一个头节点
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if (NULL == L)
    {
        printf("创建失败\n");
        return NULL;
    }

    L->len = 0;
    L->next = NULL;
    L->prio = NULL;

    printf("链表创建成功\n");
    return L;
}

        2)判空

// 判空
int list_empty(NodePtr L)
{
    return L->next == L;
}

        3)申请封装数据

// 申请封装数据
NodePtr apply_node(datatype e)
{
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        printf("数据类型不合法,封装失败\n");
        return NULL;
    }

    p->data = e;
    p->next = NULL;

    return p;
}

        4)按位置查找

// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{
    if (NULL == L || list_empty(L) || pos > L->len || pos < 0)
    {
        printf("查找失败\n");
        return NULL;
    }

    NodePtr q = L;

    for (int i = 0; i < pos; i++)
    {
        q = q->next;
    }

    printf("查找成功\n");
    return q;
}

        5)头插

// 头插
int list_insert_head(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("插入失败\n");
        return -1;
    }

    NodePtr p = apply_node(e);
    if (NULL == p)
    {
        printf("封装失败\n");
        return -1;
    }

    p->next = L->next;
    L->next = p;

    L->len++;

    printf("插入成功\n");
    return 0;
}

        6)尾插

// 尾插
int list_insert_tail(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("尾插插入失败\n");
        return -1;
    }

    // 找到最后一个节点
    NodePtr q = list_search_pos(L, L->len);

    // 封装节点
    NodePtr p = apply_node(e);

    // 插入逻辑
    p->next = q->next;
    q->next = p;

    L->len++;

    printf("尾插插入成功\n");

    return 0;
}

        7)头删

//头删
int list_delete_head(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("头删失败\n");
        return -1;
    }
    
    NodePtr p = L->next;
    L->next = p->next;
    free(p);
    p = NULL;

    L->len--;

    printf("头删成功\n");
    return 0;
}

        8)链表删除

// 链表删除
void list_destroy(NodePtr L)
{
    if (NULL == L )
    {
        printf("删除失败\n");
        return;
    }
    
    while (L->next == L)
    {
        list_delete_head(L);
    }
    

    free(L);
    L = NULL;
    
    printf("删除成功\n");
    return ;
}

        9)完整代码

00.h

#ifndef day16_1_flag_h
#define day16_1_flag_h
#include <myhead.h>

typedef char datatype;

typedef struct Node
{
    union 
    {
        int len;
        datatype data;
    };

    struct Node *next;
    
}Node,*NodePtr;

NodePtr list_create();

int  list_empty(NodePtr L);

NodePtr apply_node(datatype e);

NodePtr list_search_pos(NodePtr L,datatype pos);

int list_insert_tail(NodePtr L,datatype e);

int list_insert_head(NodePtr L,datatype e);

int list_show(NodePtr L);

int list_delete_head(NodePtr L);

void list_destroy(NodePtr L);

#endif // day16_1_flag_h

00.c

#include "00.h"
#define MAX 50

// 创建链表
NodePtr list_create()
{
    // 在堆区申请一个头节点
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if (NULL == L)
    {
        printf("创建失败\n");
        return NULL;
    }

    L->len = 0;
    L->next = L; // 头节点指针域指向自己

    printf("链表创建成功\n");
    return L;
}

// 判空
int list_empty(NodePtr L)
{
    return L->next == L;
}

// 申请封装数据
NodePtr apply_node(datatype e)
{
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        printf("数据类型不合法,封装失败\n");
        return NULL;
    }

    p->data = e;
    p->next = NULL;

    return p;
}

// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{
    if (NULL == L || list_empty(L) || pos > L->len || pos < 0)
    {
        printf("查找失败\n");
        return NULL;
    }

    NodePtr q = L;

    for (int i = 0; i < pos; i++)
    {
        q = q->next;
    }

    printf("查找成功\n");
    return q;
}

// 头插
int list_insert_head(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("插入失败\n");
        return -1;
    }

    NodePtr p = apply_node(e);
    if (NULL == p)
    {
        printf("封装失败\n");
        return -1;
    }

    p->next = L->next;
    L->next = p;

    L->len++;

    printf("插入成功\n");
    return 0;
}

// 尾插
int list_insert_tail(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("尾插插入失败\n");
        return -1;
    }

    // 找到最后一个节点
    NodePtr q = list_search_pos(L, L->len);

    // 封装节点
    NodePtr p = apply_node(e);

    // 插入逻辑
    p->next = q->next;
    q->next = p;

    L->len++;

    printf("尾插插入成功\n");

    return 0;
}

//链表遍历
int list_show(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("遍历失败\n");
        return -1;
    }

    NodePtr q = L->next;

    while(q !=L)
    {
        printf("%c",q->data);
        q = q->next;
    }
    putchar(10);
    printf("遍历成功\n");

    return 0;
}

//头删
int list_delete_head(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("头删失败\n");
        return -1;
    }
    
    NodePtr p = L->next;
    L->next = p->next;
    free(p);
    p = NULL;

    L->len--;

    printf("头删成功\n");
    return 0;
}

// 链表删除
void list_destroy(NodePtr L)
{
    if (NULL == L )
    {
        printf("删除失败\n");
        return;
    }
    
    while (L->next == L)
    {
        list_delete_head(L);
    }
    

    free(L);
    L = NULL;
    
    printf("删除成功\n");
    return ;
}

00main.c

#include "00.h"

int main(int argc, char const *argv[])
{
    NodePtr L = list_create();
    if (NULL == L )
    {
        return -1;
    }
    
    list_insert_head(L,'H');
    list_show(L);
    list_insert_head(L,'e');
    list_show(L);
    list_insert_head(L,'l');
    list_show(L);
    list_insert_head(L,'l');
    list_show(L);
    list_insert_head(L,'o');
    list_show(L);

    list_insert_tail(L,'Z');
    list_show(L);

    list_delete_head(L);
    list_show(L);

    list_destroy(L);
    list_show(L);
    return 0;
}

        10)约瑟夫环问题

00.h

#ifndef day16_1_flag_h
#define day16_1_flag_h
#include <myhead.h>

typedef int datatype;

typedef struct Node
{
    union 
    {
        int len;
        datatype data;
    };

    struct Node *next;
    
}Node,*NodePtr;

NodePtr list_create();

int  list_empty(NodePtr L);

NodePtr apply_node(datatype e);

NodePtr list_search_pos(NodePtr L,datatype pos);

int list_insert_tail(NodePtr L,datatype e);

int list_insert_head(NodePtr L,datatype e);

int list_show(NodePtr L);

int list_delete_head(NodePtr L);

void list_destroy(NodePtr L);

// 任意位置删除
int list_delete_pos(NodePtr L, int pos);

//按位置取值
int list_pos_value(NodePtr L,int pos);
#endif // day16_1_flag_h

00.c

#include "00.h"
#define MAX 50

// 创建链表
NodePtr list_create()
{
    // 在堆区申请一个头节点
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if (NULL == L)
    {
        printf("创建失败\n");
        return NULL;
    }

    L->len = 0;
    L->next = L; // 头节点指针域指向自己

    printf("链表创建成功\n");
    return L;
}

// 判空
int list_empty(NodePtr L)
{
    return L->next == L;
}

// 申请封装数据
NodePtr apply_node(datatype e)
{
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        printf("数据类型不合法,封装失败\n");
        return NULL;
    }

    p->data = e;
    p->next = NULL;

    return p;
}

// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{
    if (NULL == L || list_empty(L) || pos > L->len || pos < 0)
    {
        printf("查找失败\n");
        return NULL;
    }

    NodePtr q = L;

    for (int i = 0; i < pos; i++)
    {
        q = q->next;
    }

    printf("查找成功\n");
    return q;
}

// 头插
int list_insert_head(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("插入失败\n");
        return -1;
    }

    NodePtr p = apply_node(e);
    if (NULL == p)
    {
        printf("封装失败\n");
        return -1;
    }

    p->next = L->next;
    L->next = p;

    L->len++;

    printf("插入成功\n");
    return 0;
}

// 尾插
int list_insert_tail(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("尾插插入失败\n");
        return -1;
    }

    // 找到最后一个节点
    NodePtr q = list_search_pos(L, L->len);

    // 封装节点
    NodePtr p = apply_node(e);

    // 插入逻辑
    p->next = q->next;
    q->next = p;

    L->len++;

    printf("尾插插入成功\n");

    return 0;
}

//链表遍历
int list_show(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("遍历失败\n");
        return -1;
    }

    NodePtr q = L->next;

    while(q !=L)
    {
        printf("%d\t",q->data);
        q = q->next;
    }
    putchar(10);
    printf("遍历成功\n");

    return 0;
}

//头删
int list_delete_head(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("头删失败\n");
        return -1;
    }
    
    NodePtr p = L->next;
    L->next = p->next;
    free(p);
    p = NULL;

    L->len--;

    printf("头删成功\n");
    return 0;
}

// 链表删除
void list_destroy(NodePtr L)
{
    if (NULL == L )
    {
        printf("删除失败\n");
        return;
    }
    
    while (L->next == L)
    {
        list_delete_head(L);
    }
    

    free(L);
    L = NULL;
    
    printf("删除成功\n");
    return ;
}

// 任意位置删除
int list_delete_pos(NodePtr L, int pos)
{
    if (NULL == L || pos > L->len + 1 || pos < 1)
    {
        printf("删除失败\n");
        return -1;
    }

    NodePtr q = list_search_pos(L, pos - 1);

    NodePtr p = q->next;
    q->next = p->next;
    free(p);
    p = NULL;

    L->len--;
    printf("删除成功\n");
    return 0;
}

 00main.c

#include "00.h"

int main(int argc, char const *argv[])
{
    //创建列表
    NodePtr L = list_create();
    if (NULL == L)
    {
        return -1;
    }

    //num 人数  die 死亡序号
    int num, die = 0;
    
    printf("输入参与约瑟夫游戏的人数:\n");
    scanf("%d", &num);
    printf("报数到多少被杀掉:\n");
    scanf("%d", &die);

    //为参与者赋予代号
    for (int i = 0; i < num; i++)
    {
        list_insert_head(L, i+1);
    }

    list_show(L);

    //day 日期   all 总人数   death 死者数组
    int day = 0;
    int all = num;
    datatype death[100] = {0};  //死者序列
    NodePtr p = L;
    while (num>all/2)
    {
        for (int i = 0; i < die-1; i++)
        {
            if (p->next == L)//到头节点时多偏移一位,略过头节点
            {
                p = p->next;
            }
            
            p = p->next;
        }

        int kill = p->next->data;           //死者代号
        death[day] = kill;                  //将死者代号存入死者名列
        printf("%d\n",kill);
        list_delete_head(p->next);          //删除死者位置
        day++;                              //日期推移
        num--;                              //人数减一
    }

    printf("死者代号及顺序依次为:\n");
    for (int i = 0; i < day; i++)
    {
        printf("%d\t", death[i]);
    }
    putchar(10);

    return 0;
}

双向循环链表

00.h

#ifndef day16_1_flag_h
#define day16_1_flag_h
#include <myhead.h>

typedef char datatype;

typedef struct Node
{
    union 
    {
        int len;
        datatype data;
    };

    struct Node *next;
    struct Node *prio;
    
}Node,*NodePtr;

NodePtr list_create();

int  list_empty(NodePtr L);

NodePtr apply_node(datatype e);

NodePtr list_search_pos(NodePtr L,datatype pos);

int list_insert_tail(NodePtr L,datatype e);

int list_insert_head(NodePtr L,datatype e);

int list_show(NodePtr L);

int list_delete_head(NodePtr L);

void list_destroy(NodePtr L);

// 任意位置删除
int list_delete_pos(NodePtr L, int pos);

//按位置取值
int list_pos_value(NodePtr L,int pos);

//按位置修改
int list_change_pos(NodePtr L,int pos,datatype e);
#endif // day16_1_flag_h

00.c

#include "00.h"
#define MAX 50

// 创建链表
NodePtr list_create()
{
    // 在堆区申请一个头节点
    NodePtr L = (NodePtr)malloc(sizeof(Node));
    if (NULL == L)
    {
        printf("创建失败\n");
        return NULL;
    }

    L->len = 0;
    L->next = L; // 头节点指针域指向自己
    L->prio = L;

    printf("链表创建成功\n");

    return L;
}

// 判空
int list_empty(NodePtr L)
{
    return L->next == L;
}

// 申请封装数据
NodePtr apply_node(datatype e)
{
    NodePtr p = (NodePtr)malloc(sizeof(Node));
    if (NULL == p)
    {
        printf("数据类型不合法,封装失败\n");
        return NULL;
    }

    p->data = e;
    p->next = NULL;
    p->prio = NULL;

    return p;
}

// 按位置查找
NodePtr list_search_pos(NodePtr L, datatype pos)
{
    if (NULL == L || list_empty(L) || pos > L->len || pos < 0)
    {
        printf("查找失败\n");
        return NULL;
    }

    NodePtr q = L;

    for (int i = 0; i < pos; i++)
    {
        q = q->next;
    }

    printf("查找成功\n");
    return q;
}

// 头插
int list_insert_head(NodePtr L, datatype e)
{
    if (NULL == L)
    {
        printf("数据类型不合法,头插失败\n");
        return -1;
    }

    NodePtr p = apply_node(e);
    if (NULL == p)
    {
        printf("数据封装失败,头插失败\n");
        return -1;
    }

    if (list_empty(L))
    {
        p->prio = L;
        p->next = L->next; // p->next = L
        L->next = p;
        L->prio = p;
    }
    else
    {
        p->prio = L;
        p->next = L->next;

        L->next->prio = p; // p->next->prio =p;
        L->next = p;
    }

    L->len++;

    printf("插入成功\n");
    return 0;
}

// 尾插
int list_insert_tail(NodePtr L, datatype e)
{
    // 判断逻辑
    if (NULL == L)
    {
        printf("尾插插入失败\n");
        return -1;
    }

    // 找到最后一个节点
    NodePtr q = list_search_pos(L, L->len);

    // 封装节点
    NodePtr p = apply_node(e);

    // 插入逻辑
    p->next = q->next;
    p->prio = q;

    q->next = p;

    L->len++;

    printf("尾插插入成功\n");
    return 0;
}

// 链表遍历
int list_show(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("遍历失败\n");
        return -1;
    }

    NodePtr q = L->next;

    while (q != L)
    {
        printf("%c", q->data);
        q = q->next;
    }
    putchar(10);
    printf("遍历成功\n");

    return 0;
}

// 头删
int list_delete_head(NodePtr L)
{
    if (NULL == L || list_empty(L))
    {
        printf("头删失败\n");
        return -1;
    }

    NodePtr p = L->next;
    L->next = p->next;
    p->next->prio = L;
    free(p);
    p = NULL;

    L->len--;

    printf("头删成功\n");

    return 0;
}

// 链表删除
void list_destroy(NodePtr L)
{
    if (NULL == L)
    {
        printf("删除失败\n");
        return;
    }

    while (L->next == L)
    {
        list_delete_head(L);
    }

    free(L);
    L = NULL;

    printf("删除成功\n");
    return;
}

// 任意位置删除
int list_delete_pos(NodePtr L, int pos)
{
    if (NULL == L || pos > L->len + 1 || pos < 1)
    {
        printf("删除失败\n");
        return -1;
    }

    NodePtr q = list_search_pos(L, pos - 1);

    NodePtr p = q->next;
    q->next = p->next;
    p->next->prio = q;
    free(p);
    p = NULL;
    // NodePtr p = L->next;
    // L->next = p->next;
    // p->next->prio = L;
    // free(p);
    // p = NULL;

    L->len--;
    printf("按位置删除成功\n");

    return 0;
}

//按位置修改
int list_change_pos(NodePtr L,int pos,datatype e)
{
    if (NULL == L || pos > L->len + 1 || pos < 1)
    {
        printf("修改失败\n");
        return -1;
    }

    NodePtr q = list_search_pos(L, pos);

    q->data = e;

    printf("按位置修改成功\n");

    return 0;
}
#include "00.h"

int main(int argc, char const *argv[])
{
    NodePtr L = list_create();
    if (NULL == L )
    {
        return -1;
    }

    putchar(10);

    list_insert_head(L,'H');
    list_insert_head(L,'e');
    list_insert_head(L,'l');
    list_insert_head(L,'l');
    list_insert_head(L,'o');
    list_show(L);
    putchar(10);

    list_insert_tail(L,'Z');
    list_show(L);
    putchar(10);

    list_delete_head(L);
    list_show(L);
    putchar(10);

    list_delete_pos(L,3);
    list_show(L);
    putchar(10);

    list_change_pos(L,4,'A');
    list_show(L);
    putchar(10);

    list_destroy(L);
    list_show(L);
    putchar(10);

    return 0;
}

实现结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1944197.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s中部署Jenkins、SonarQube、StorageClass部署流程

部署Jenkins 系统环境&#xff1a; • kubernetes 版本&#xff1a;1.23.3 • jenkins 版本&#xff1a;2.172 • jenkins 部署示例文件 Github 地址&#xff1a;https://github.com/my-dlq/blog-example/tree/master/jenkins-deploy 一、设置存储目录 在 Kubenetes 环境下…

Kolla-Ansible的确是不支持CentOS-Stream系列产品了

看着OpenStack最新的 C 版本出来一段时间了&#xff0c;想尝个鲜、用Kolla-Ansible进行容器化部署&#xff0c;结果嘛。。。 根据实验结果&#xff0c;自OpenStack Bobcat版本开始&#xff0c;Kolla-Ansible就适合在CentOS系列产品上部署了&#xff0c;通过对 Bobcat和Caracal…

llama模型,nano

目录 llama模型 Llama模型性能评测 nano模型是什么 Gemini Nano模型 参数量 MMLU、GPQA、HumanEval 1. MMLU(Massive Multi-task Language Understanding) 2. GPQA(Grade School Physics Question Answering) 3. HumanEval llama模型 Large Language Model AI Ll…

Python教程(一):环境搭建及PyCharm安装

目录 引言1. Python简介1.1 编译型语言 VS 解释型语言 2. Python的独特之处3. Python应用全览4. Python版本及区别5. 环境搭建5.1 安装Python&#xff1a; 6. 开发工具&#xff08;IDE&#xff09;6.1 PyCharm安装教程6.2 永久使用教程 7. 编写第一个Hello World结语 引言 在当…

微服务实战系列之玩转Docker(六)

前言 刚进入大暑&#xff0c;“清凉不肯来&#xff0c;烈日不肯暮”&#xff0c;空调开到晚&#xff0c;还是满身汗。——碎碎念 我们知道&#xff0c;仓库可见于不同领域&#xff0c;比如粮食仓库、数据仓库。在容器领域&#xff0c;自然也有镜像仓库&#xff08;registry&…

【案例】使用React+redux实现一个Todomvc

About 大家好&#xff0c;我是且陶陶&#xff0c;今天跟大家分享一个redux的todoList案例&#xff0c;通过这个案例能够快速掌握redux的基本知识点&#x1f339; ❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…❤️…

超声波眼镜清洗机什么牌子好?入门级家用超声波清洗机推荐

戴眼镜的人一定都有对眼镜店的超声波清洗机清洗过的眼镜惊讶过&#xff0c;洗过之后光洁如新&#xff0c;镜片清澈透亮。最初笔者以为超声波清洗机只能用来清洗眼镜&#xff0c;没想到它还能清洗很多小玩意儿。目前市面上的超声波清洗机品牌繁多&#xff0c;今天笔者来教教大家…

QtCreator和QtDesignStudio最佳实践

一、QTC和QDS工作流概述 很多初学者对 QDS(Qt Design Studio) 和 QTC(Qt Creator)如何配合经常存有疑问&#xff0c;本文介绍具体的工作流程。 工作流程 1.产品设计&#xff1a;通过PS、Figma、XD等专业工具设计页面视觉和原型。 2.QDS 原型制作&#xff1a;导入设计源文件、…

计算机网络-配置双机三层互联(静态路由方式)

目录 交换机工作原理路由器工作原理路由信息表组成部分路由器发决策 ARP工作原理配置双机三层互联&#xff08;静态路由方式&#xff09; 交换机工作原理 MAC自学习过程 初始状态&#xff1a; 刚启动的交换机的MAC地址表是空的。 学习过程&#xff1a; 当交换机收到一个数据帧…

【QML之·组件】

系列文章目录 文章目录 前言一、概述2.QML组件的重要性 二、实例演示总结 前言 组件是QML中的一个重要概念&#xff0c;它是用户界面的构建块。组件是可重用的&#xff0c;可以在不同的界面中使用。每个组件都有自己的属性、信号和方法&#xff0c;可以通过绑定和事件处理来实现…

C# 与C++ cli

cli CLI&#xff08;Command Line Interface&#xff09;是一种通过命令行界面与计算机系统进行交互的方式。它提供了一种以文本形式输入命令和接收系统输出的方法&#xff0c;用于执行各种操作和管理计算机系统。以下是CLI的详细解释&#xff1a; 一、定义与基本概念 定义&…

时间序列数据增强方法概述

时间序列数据增强方法概述 时间序列数据增强是一种提高模型泛化能力和预测准确性的技术&#xff0c;通过在原始数据集上生成新的样本&#xff0c;可以增加模型训练过程中的多样性和鲁棒性。本文将介绍几种常用的时间序列数据增强方法&#xff0c;并提供相应的Python代码示例。…

OS Copilot初体验的感受与心得

本文介绍体验操作系统智能助手OS Copilot后&#xff0c;个人的一些收获、体验等。 最近&#xff0c;抽空体验了阿里云的操作系统智能助手OS Copilot&#xff0c;在这里记录一下心得与收获。总体观之&#xff0c;从个人角度来说&#xff0c;感觉这个OS Copilot确实抓住了不少开发…

宝塔国际版Docker Manager 3.4获取镜像列表报错解决办法

宝塔国际版安装Docker Manager 3.4,遇到获取镜像列表的时候报错。 解决办法 找到:/www/server/panel/plugin/docker/docker_main.py文件 替换函数utc_to_local 原代码 # UTC时间转换为时间戳def utc_to_local(self, utc_time_str, utc_format=%Y-%m-%dT%H:%M:%S):

邮件安全篇:如何防止邮件泄密?

本文主要讨论组织内部用户违反保密规定通过邮件泄密的场景。其他场景导致邮箱泄密的问题&#xff08;如账号被盗、邮件系统存在安全漏洞等&#xff09;不在本文的讨论范围。本文主要从邮件系架构设计、邮件数据防泄漏系统、建立健全规章制度、安全意识培训等方面分别探讨。 1. …

SpringBoot整合Spring Boot Admin实现监控

目录 基本操作流程&#xff1a; 服务端 server 0.创建一个springboot项目 1.导入依赖 2.添加配置信息 3.在启动类添加注解 4.运行 客户端client 1.添加依赖 2.添加配置信息 3.运行 基本操作流程&#xff1a; 服务端 server 0.创建一个springboot项目 1.导入依赖 …

Wordpress安装到win10(2024年7月)

目录 1.wordpress介绍 2下载应用 2.1.wordpress 2.2XAMPP 2.3 PHPmyadmin 3.配置应用 3.1XAMPP进程 3.2 文件配置 3.3 phpmyadmin配置 4.配置网页 4.1 数据库创建 4.2 安装wordpress 5.进入面板 6.总结 1.wordpress介绍 WordPress是一个开源内容管理系统&#xff0…

域名解析到ipv6,并用CF隐藏端口

要求&#xff1a;域名解析到 IPv6 地址并隐藏端口 ‍ 效果&#xff1a;用域名 https://myhalo.soulio.top​ 访问http://[2409:8a62:867:4f12:56c7:5508:f7x6:8]:8080​。唯一缺点是延迟有点高。 ​​ ‍ 难度&#xff1a;需要有一定域名解析、cloudflare使用基础 ‍ 实…

深度学习实战笔记2实战Kaggle比赛:预测房价

此数据集由Bart de Cock于2011年收集 :cite:De-Cock.2011&#xff0c; 涵盖了2006-2010年期间亚利桑那州埃姆斯市的房价。 这个数据集是相当通用的&#xff0c;不会需要使用复杂模型架构。 它比哈里森和鲁宾菲尔德的波士顿房价 数据集要大得多&#xff0c;也有更多的特征。 1下…

Linux云计算 |【第一阶段】SERVICES-DAY6

主要内容&#xff1a; Linux容器基础、Linux容器管理、podman命令行、管理容器进阶 实操前骤&#xff1a;安装 RHEL8.2 虚拟机 1.选择软件包&#xff1a;rhel-8.2-x86-dvd.iso&#xff1b; 2.内存2048M&#xff1b; 3.时区选择亚洲-上海&#xff0c;带GUI的服务器&#xff1b…