数据结构 双向循环链表

双向循环链表

定义

  • 记录元素的同时要记录前一个结点和后一个结点的地址
  • 再头尾插入删除结点 时间复杂度O(1)
ElemType elem;
struct DNode *prev;
struct DNode *next;
  • 用柔性数组实现 任意类型元素双向循环链表
// struct DNode *node = (struct DNode*)malloc(DNODESIZE + elemSize);
// elemSize 是要存储元素类型的字节数
struct DNode *prev;
struct DNode *next;
char elem[0]; // 柔性数组

双向循环链表实现

结构体定义

#define SUCCESS 0
#define FAILURE -1

typedef int ElemType;

// 双向(循环)链表结点
struct DNode {
    ElemType elem; // 元素
    struct DNode *prev; // 指向上一个结点
    struct DNode *next; // 指向下一个结点
};

#define DNODESIZE sizeof(struct DNode)

// 双向循环链表类型
typedef struct DNode* DLinkedList;

静态函数列表

// 创建双向(循环)链表的结点
static struct DNode *create_dnode(ElemType elem, struct DNode *prev, struct DNode *next);

// 再结点node后面插入结点
static int insert_after(struct DNode *node, ElemType elem);

// 再结点node前面插入结点
static int insert_before(struct DNode *node, ElemType elem);

// 删除node结点
static int delete_dnode(struct DNode *node, ElemType *pElem);

// 获取pos位置上结点
struct DNode *get_dnode(DLinkedList list, size_t pos);

基础函数声明

// 创建双向循环链表   创建一个头结点   且让头结点的prev和next指向头结点
// 头结点本身不存在数据
DLinkedList create_dlinkedlist(void);

// 双向链表是否为空
bool empty_dlinkedlist(DLinkedList list);

// 双向循环链表元素个数
size_t size_dlinkedlist(DLinkedList list);

// 清空双向循环链表
void clear_dlinkedlist(DLinkedList list);

// 销毁双向循环链表
void destroy_dlinkedlist(DLinkedList list);

// 在头部插入元素
int push_front_dlinkedlist(DLinkedList list, ElemType elem);

// 在末尾插入元素
int push_back_dlinkedlist(DLinkedList list, ElemType elem);

// 在指定位置插入元素
int insert_dlinkedlist(DLinkedList list, size_t pos, ElemType elem);

// 在头部删除元素
int pop_front_dlinkedlist(DLinkedList list, ElemType *pElem);

// 在末尾删除元素
int pop_back_dlinkedlist(DLinkedList list, ElemType *pElem);

// 删除指定位置的元素
int remove_dlinkedlist(DLinkedList list, size_t pos, ElemType *pElem);

// 根据值删除元素
int delete_dlinkedlist(DLinkedList list, ElemType elem, size_t n);

// 根据条件删除元素
int delete_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n);

// 修改pos位置的元素
int update_dlinkedlist(DLinkedList list, size_t pos, ElemType newElem);

// 修改第n个oldElem为newElem
int update_elem_dlinkedlist(DLinkedList list, ElemType oldElem, ElemType newElem, size_t n);

// 修改第n个满足条件的元素为newElem
int update_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), ElemType newElem, size_t n);

// 查找pos位置的元素
ElemType* elem_of_dlinkedlist(DLinkedList list, size_t pos);

// 统计元素为elem的个数
int count_dlinkedlist(DLinkedList list, ElemType elem);

// 统计满足条件元素的个数
int count_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType));

// 查找elem元素位置
int find_dlinkedlist(DLinkedList list, ElemType elem, size_t n);

// 查找满足条件的元素位置
int find_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n);

// 正向迭代
void foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*));

// 反向迭代
void reverse_foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*));

静态函数实现

创建双向(循环)链表的结点 create_dnode
static struct DNode *create_dnode(ElemType elem, struct DNode *prev, struct DNode *next) {
    struct DNode *node = (struct DNode*)malloc(DNODESIZE);
    if (node != NULL) { // 申请成功  赋值
        node->elem = elem;
        node->prev = prev;
        node->next = next;
    }
    return node;
}
再结点node后面插入结点 insert_after
// 在结点1后面插入元素
/*
node为结点1,node->next为结点3,要插入结点2(prev已经指向结点1,next已经指向结点3)
先将结点3的prev指向结点2
再将结点1的next指向结点2
*/
static int insert_after(struct DNode *node, ElemType elem) {
    struct DNode *insNode = create_dnode(elem, node, node->next); // 结点2
    if (insNode == NULL) {
        return FAILURE;
    }
    node->next->prev = insNode; // 结点3的prev指向结点2
    node->next = insNode; // 结点1的next指向结点2
    return SUCCESS;
}
再结点node前面插入结点 insert_before
// 在结点1前面插入元素
/*
node为结点1,node->prev为结点3,要插入结点2(prev已经指向结点3,next已经指向结点1)
先将结点3的next指向结点2
再将结点1的prev指向结点2
*/
static int insert_before(struct DNode *node, ElemType elem) {
    struct DNode *insNode = create_dnode(elem, node->prev, node); // 结点2
    if (insNode == NULL) {
        return FAILURE;
    }
    node->prev->next = insNode; // 结点3的next指向结点2
    node->prev = insNode; // 将结点1的prev指向结点2
    return SUCCESS;
}
删除node结点 delete_dnode
// 删除node结点
static int delete_dnode(struct DNode *node, ElemType *pElem) {
    if (pElem != NULL) {
        *pElem = node->elem; // 返回删除的元素
    }
    node->next->prev = node->prev;
    node->prev->next = node->next;
    free(node); // 释放删除的结点
    return SUCCESS;
}
获取pos位置上结点 get_dnode
// 获取pos位置上结点
struct DNode *get_dnode(DLinkedList list, size_t pos) {
    struct DNode *node = list->next;
    size_t i;
    for (i = 1; i < pos && node != list; ++i) {
        node = node->next;
    }
    if (node == list && i < pos) {
        return NULL;
    }
    return node;
}

基础函数实现

创建双向循环链表 create_dlinkedlist
// 创建一个头结点   且让头结点的prev和next指向头结点
// 头结点本身不存在数据
DLinkedList create_dlinkedlist(void) {
    DLinkedList list = (DLinkedList)malloc(DNODESIZE);
    if (list != NULL) {
        list->prev = list->next = list; // 没有元素所以指针都指向自己
    }
    return list;
}
双向链表是否为空 empty_dlinkedlist
// 双向链表是否为空
bool empty_dlinkedlist(DLinkedList list) {
    assert(list != NULL);
    return list->prev == list && list->next == list; // 等于自己就为空
}
双向循环链表元素个数 size_dlinkedlist
size_t size_dlinkedlist(DLinkedList list) {
    assert(list != NULL);
    size_t size = 0;
    struct DNode *node;
    for (node = list->next; node != list; node = node->next) { // 循环到头结点结束
        ++size;
    }
    return size;
}
清空双向循环链表 clear_dlinkedlist
void clear_dlinkedlist(DLinkedList list) {
    assert(list != NULL);
    struct DNode *node, *next;
    for (node = list->next; node != list; node = node->next) {
        next = node->next; // 先记录下一个地址
        free(node); // 每个结点都要释放,否在会导致内存泄漏
    }
    list->prev = list->next = list;
}
销毁双向循环链表 destroy_dlinkedlist
void destroy_dlinkedlist(DLinkedList list) {
    assert(list != NULL);
    clear_dlinkedlist(list);
    free(list);
}
在头部插入元素 push_front_dlinkedlist
int push_front_dlinkedlist(DLinkedList list, ElemType elem) {
    assert(list != NULL);
    return insert_after(list, elem); // 调用静态函数
    // return insert_before(list->next, elem);
}
在末尾插入元素 push_back_dlinkedlist
int push_back_dlinkedlist(DLinkedList list, ElemType elem) {
    assert(list != NULL);
    return insert_before(list, elem);
    // return insert_after(list->prev, elem);
}
在指定位置插入元素 insert_dlinkedlist
int insert_dlinkedlist(DLinkedList list, size_t pos, ElemType elem) {
    assert(list != NULL);
    if (pos == 0) {
        return FAILURE;
    }
    struct DNode *node = get_dnode(list, pos); // 先获取指定位置的元素  然后再其之前插入元素
    if (node == NULL) {
        return FAILURE;
    }
    return insert_before(node, elem);
}
在头部删除元素 pop_front_dlinkedlist
int pop_front_dlinkedlist(DLinkedList list, ElemType *pElem) {
    assert(list != NULL);
    if (list->next == list) {
        return FAILURE;
    }
    return delete_dnode(list->next, pElem);
}
在末尾删除元素 pop_back_dlinkedlist
int pop_back_dlinkedlist(DLinkedList list, ElemType *pElem) {
    assert(list != NULL);
    if (list->prev == list) {
        return FAILURE;
    }
    return delete_dnode(list->prev, pElem);
}
删除指定位置的元素 remove_dlinkedlist
int remove_dlinkedlist(DLinkedList list, size_t pos, ElemType *pElem) {
    assert(list != NULL);
    if (pos == 0) {
        return FAILURE;
    }
    struct DNode *node = get_dnode(list, pos); // 先获取要删除元素的结点地址
    if (node == NULL || node == list) {
        return FAILURE;
    }
    return delete_dnode(node, pElem);
}
根据值删除元素 delete_dlinkedlist

n为0全部删除

int delete_dlinkedlist(DLinkedList list, ElemType elem, size_t n) {
    assert(list != NULL);
    struct DNode *node = list->next;
    struct DNode *next = NULL;
    int cnt = 0;
    while (node != list) {
        if (node->elem == elem) {
            if (n == 0) {
                next = node->next;
                delete_dnode(node, NULL);
                node = next;
                ++cnt;
            } else {
                if (--n == 0) {
                    delete_dnode(node, NULL);
                    return 1;
                } else {
                    node = node->next; // n不为零 向后移
                }
            }
        } else {
            node = node->next; // 不等于elem 向后移
        }
    }
    return cnt;
}
根据条件删除元素 delete_condition_dlinkedlist

自定义回调函数condition n为0全部删除

int delete_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n) {
    assert(list != NULL && condition != NULL);
    struct DNode *node = list->next;
    struct DNode *next = NULL;
    int cnt = 0;
    while (node != list) {
        if (condition(node->elem)) {
            if (n == 0) {
                next = node->next;
                delete_dnode(node, NULL);
                node = next;
                ++cnt;
            } else {
                if (--n == 0) {
                    delete_dnode(node, NULL);
                    return 1;
                } else {
                    node = node->next;
                }
            }
        } else {
            node = node->next;
        }
    }
    return cnt;
}
修改pos位置的元素 update_dlinkedlist
int update_dlinkedlist(DLinkedList list, size_t pos, ElemType newElem) {
    assert(list != NULL);
    if (pos == 0) {
        return FAILURE;
    }
    struct DNode *node = get_dnode(list, pos); // 获取要修改元素的地址
    if (node == NULL || node == list) {
        return FAILURE;
    }
    node->elem = newElem;
    return SUCCESS;
}
修改第n个oldElem为newElem update_elem_dlinkedlistElemType newElem, size_t n);

n为0全部修改

int update_elem_dlinkedlist(DLinkedList list, ElemType oldElem, ElemType newElem, size_t n) {
    assert(list != NULL);
    int cnt = 0;
    struct DNode *node = list->next;
    for (; node != list; node = node->next) {
        if (node->elem == oldElem) {
            if (n == 0) {
                node->elem = newElem;
                ++cnt;
            } else {
                if (--n == 0) {
                    node->elem = newElem;
                    return 1;
                }
            }
        }
    }
    return cnt;
}
修改第n个满足条件的元素为newElem update_condition_dlinkedlist

自定义回调函数condition n为0全部修改

int update_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), ElemType newElem, size_t n) {
    assert(list != NULL && condition != NULL);
    int cnt = 0;
    struct DNode *node = list->next;
    for (; node != list; node = node->next) {
        if (condition(node->elem)) {
            if (n == 0) {
                node->elem = newElem;
                ++cnt;
            } else {
                if (--n == 0) {
                    node->elem = newElem;
                    return 1;
                }
            }
        }
    }
    return cnt;
}
查找pos位置的元素 Type* elem_of_dlinkedlist
ElemType* elem_of_dlinkedlist(DLinkedList list, size_t pos) {
    assert(list != NULL);
    if (pos == 0) {
        return NULL;
    }
    struct DNode *node = get_dnode(list, pos);
    if (node == NULL || node == list) {
        return NULL;
    }
    return &node->elem; // 返回地址
}
统计元素为elem的个数 count_dlinkedlist
int count_dlinkedlist(DLinkedList list, ElemType elem) {
    assert(list != NULL);
    int cnt = 0;
    struct DNode *node = list->next;
    for (; node != list; node = node->next) {
        if (node->elem == elem) {
            ++cnt;
        }
    }
    return cnt;
}
统计满足条件元素的个数 count_condition_dlinkedlist

自定义回调函数condition

int count_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType)) {
    assert(list != NULL && condition != NULL);
    int cnt = 0;
    struct DNode *node = list->next;
    for (; node != list; node = node->next) {
        if (condition(node->elem)) {
            ++cnt;
        }
    }
    return cnt;
}
查找elem元素位置 find_dlinkedlist
int find_dlinkedlist(DLinkedList list, ElemType elem, size_t n) {
    assert(list != NULL);
    if (n == 0) {
        return 0;
    }
    struct DNode *node = list->next;
    size_t pos = 0;
    for (; node != list; node = node->next) {
        ++pos;
        if (node->elem == elem) {
            if (--n == 0) {
                return pos;
            }
        }
    }
    return 0; // 0为没有找到
}
查找满足条件的元素位置 find_condition_dlinkedlist

自定义回调函数condition

int find_condition_dlinkedlist(DLinkedList list, bool (*condition)(ElemType), size_t n) {
    assert(list != NULL && condition != NULL);
    if (n == 0) {
        return 0;
    }
    struct DNode *node = list->next;
    size_t pos = 0;
    for (; node != list; node = node->next) {
        ++pos;
        if (condition(node->elem)) {
            if (--n == 0) {
                return pos;
            }
        }
    }
    return 0;
}
正向迭代 foreach_dlinkedlist

可以实现打印等功能

void foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*)) {
    assert(list != NULL && foreach != NULL);
    struct DNode *node;
    for (node = list->next; node != list; node = node->next) {
        foreach(&node->elem);
    }
}
反向迭代 reverse_foreach_dlinkedlist
void reverse_foreach_dlinkedlist(DLinkedList list, void (*foreach)(ElemType*)) {
    assert(list != NULL && foreach != NULL);
    struct DNode *node;
    for (node = list->prev; node != list; node = node->prev) {
        foreach(&node->elem);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值