学习记录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;
}

实现结果

相关推荐
我不会编程5556 小时前
Python Cookbook-5.1 对字典排序
开发语言·数据结构·python
云上艺旅6 小时前
K8S学习之基础七十四:部署在线书店bookinfo
学习·云原生·容器·kubernetes
你觉得2056 小时前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义下载方法
大数据·人工智能·python·gpt·学习·机器学习·aigc
owde7 小时前
顺序容器 -list双向链表
数据结构·c++·链表·list
第404块砖头7 小时前
分享宝藏之List转Markdown
数据结构·list
蒙奇D索大7 小时前
【数据结构】第六章启航:图论入门——从零掌握有向图、无向图与简单图
c语言·数据结构·考研·改行学it
A旧城以西8 小时前
数据结构(JAVA)单向,双向链表
java·开发语言·数据结构·学习·链表·intellij-idea·idea
无所谓จุ๊บ8 小时前
VTK知识学习(50)- 交互与Widget(一)
学习·vtk
FAREWELL000758 小时前
C#核心学习(七)面向对象--封装(6)C#中的拓展方法与运算符重载: 让代码更“聪明”的魔法
学习·c#·面向对象·运算符重载·oop·拓展方法
吴梓穆8 小时前
UE5学习笔记 FPS游戏制作38 继承标准UI
笔记·学习·ue5