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

双向链表

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;
}

实现结果

相关推荐
EterNity_TiMe_23 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
sanguine__26 分钟前
java学习-集合
学习
lxlyhwl26 分钟前
【STK学习】part2-星座-目标可见性与覆盖性分析
学习
nbsaas-boot27 分钟前
如何利用ChatGPT加速开发与学习:以BPMN编辑器为例
学习·chatgpt·编辑器
CV学术叫叫兽1 小时前
一站式学习:害虫识别与分类图像分割
学习·分类·数据挖掘
daiyang123...1 小时前
测试岗位应该学什么
数据结构
我们的五年1 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
kitesxian1 小时前
Leetcode448. 找到所有数组中消失的数字(HOT100)+Leetcode139. 单词拆分(HOT100)
数据结构·算法·leetcode
一棵开花的树,枝芽无限靠近你2 小时前
【PPTist】添加PPT模版
前端·学习·编辑器·html
VertexGeek2 小时前
Rust学习(八):异常处理和宏编程:
学习·算法·rust