数据结构-双向循环链表及其封装

双向循环链表

结点:

    前驱指针  prev

    数据域

    后继指针  next

typedef struct Node

{

    struct Node* node;  //前驱

    TYPE data;

    struct Node* next;  //后继

}Node;

Node* create_node(TYPE data)

{

    Node* node = malloc(sizeof(Node));

    node->data = data;

    node->prev = node;

    node->next = node;

    return node;

}

//带头结点的双向链表

void _add_list(Node* p,Node* n,TYPE data)

{

    Node* node = create_node(data);

    node->prev = p;

    node->next = n;

    p->next = node;

    n->prev = node;

}

//头添加

void add_head_list()

{

    _add_list(head,head->next,data);

}

//尾添加

void add_tail_list(Node* head,TYPE data)

{

    _add_list(head->prev,head,data);

}

//插入

bool insert_list(Node* head,size_t index,TYPE data)

{

    //n直接找到插入的index结点

    Node* n = head->next;

    for(int i = 0;i<index;i++)

    {

        n = n->next;

        if(head == n) return false;

    }

    _add_list(n->prev,n,data);

}

//删除

void _del_list(Node* node)

{

    Node* p = node->prev;

    Node* n = node->next;

    p->next->n;

    n->prev =p;

    free(node);

}

//按位置删除

bool del_index_list(Node* head,size_t index)

{

    //直接找待删除结点即可

    Node* n = head->next;

    for(int i=0;i<index;i++)

    {

        n = n->next;

        if(head == n) return false;

    }

    _del_list(n);

    return true;

}

//按值删除

bool del_value_list(Node* head,TYPE val)

{

    for(Node* n = head->next;head != n;n=n->next)

    {

        if(n->data == val)

        _del_list(n);

        return true;

    }

    return false;

}

//遍历

void show_list(Node* head)

{

    for(Node* n = head->next;head!=n;n=n->next)

    {

        printf("%d ",n->data)

    }

    printf("\n");

}

int main()

{

    Node* head = create_node(0);

    for(int i=0;i<10;i++)

    {

        add_head_list(head,i);

    }

    insert_list(head,4,88);

    show_list(head);

}

封装双向链表

双向链表

结点:

    前驱指针  prev

    数据域

    后继指针  next

数据项:

    头结点

    结点数量

特点:

    1、在任意结点都可以遍历整个链表

    2、相比单链表,删除、插入更直接

    3、已知结点位置,可以选择从前往后或者从后往前,提高链表的访问效率

 #include <stdio.h>

#include <stdlib.h>

#include <stdbool.h>

#define TYPE int

//  封装双向链表

typedef struct Node

{

    struct Node* prev;  //  前驱

    TYPE data;

    struct Node* next;  //  后继

}Node;

//  双向链表都是循环的

Node* create_node(TYPE data)

{

    Node* node = malloc(sizeof(Node));

    node->data = data;

    node->prev = node;

    node->next = node;

    return node;

}

//  双向链表

typedef struct DoubleList

{

    Node* head;

    size_t size;

}DoubleList;

//  创建链表

DoubleList* create_double_list(void)

{

    DoubleList* list = malloc(sizeof(DoubleList));

    list->head = create_node(0);

    list->size = 0;

    return list;

}

//  在前驱和后继之间添加一个新结点

static void _add_list(Node* p,Node* n,TYPE val)

{

    Node* node = create_node(val);

    p->next = node;

    n->prev = node;

    node->next = n;

    node->prev = p;

}

//  删除当前结点

static void _del_list(Node* node)

{

    Node* p = node->prev;

    Node* n = node->next;

    p->next = n;

    n->prev = p;

    free(node);

}

//  返回指定位置的结点

static Node* _index_list(DoubleList* list,size_t index)

{

    if(index >= list->size) return NULL;

    if(index < list->size/2)

    {

        //  从前往后

        Node* n = list->head->next;

        while(index--) n = n->next;

        return n;

    }

    else

    {

        //  往后找

        Node* n = list->head->prev;

        while(++index < list->size) n = n->prev;

        return n;

    }

}

//  返回指定值的结点

static Node* _value_list(DoubleList* list,TYPE data)

{

    for(Node* n=list->head->next; list->head!=n; n=n->next)

    {

        if(data == n->data) return n;  

    }

    return NULL;

}

//  头添加

void add_head_list(DoubleList* list,TYPE val)

{

    _add_list(list->head,list->head->next,val);

    list->size++;

}

//  尾添加

void add_tail_list(DoubleList* list,TYPE val)

{

    _add_list(list->head->prev,list->head,val);

    list->size++;

}

//  插入

bool insert_list(DoubleList* list,size_t index,TYPE val)

{

    Node* n = _index_list(list,index);  

    if(NULL == n) return false;

    _add_list(n->prev,n,val);

    list->size++;

    return true;

}

//  按位置修改

bool modify_index_list(DoubleList* list,size_t index,TYPE val)

{

    Node* node = _index_list(list,index);

    if(NULL == node) return false;

    node->data = val;

    return true;

}

//  按值修改 更新

size_t modify_value_list(DoubleList* list,TYPE old,TYPE val)

{

    size_t cnt = 0;

    for(Node* n=list->head->next; list->head!=n; n=n->next)

    {

        if(old == n->data)

        {

            n->data = val;

            cnt++;

        }  

    }

    return cnt;

}

//  访问

bool access_list(DoubleList* list,size_t index,TYPE* val)

{

    Node* node = _index_list(list,index);

    if(NULL == node) return false;

   

    *val = node->data;

    return true;

}

//  查询

int query_list(DoubleList* list,TYPE val)

{  

    Node* n = list->head->next;

    for(int i=0; i<list->size; i++)

    {

        if(val == n->data) return i;

        n = n->next;

    }

    return -1;

}

//  按位置删除

bool del_index_list(DoubleList* list,size_t index)

{

    Node* node = _index_list(list,index);

    if(NULL == node) return false;

    _del_list(node);

    list->size--;

    return true;

}

//  按值删除

bool del_value_list(DoubleList* list,TYPE val)

{

    Node* node = _value_list(list,val);

    if(NULL == node) return false;

    _del_list(node);

    list->size--;

    return true;

}

//  遍历

void show_list(DoubleList* list)

{

    for(Node* n=list->head->next; list->head!=n; n=n->next)

    {

        printf("%d ",n->data);  

    }

    printf("\n");

}

//  清空

void clear_list(DoubleList* list)

{

    Node* n = list->head->next;

    while(list->head!=n)

    {

        Node* temp = n;

        n = n->next;

        free(temp);

    }

    list->head->next = list->head;

    list->head->prev = list->head;

    list->size = 0;

}

//  销毁

void destory_list(DoubleList* list)

{

    clear_list(list);

    free(list->head);

    free(list);

}

int main()

{

    DoubleList* list = create_double_list();

    for(int i=0; i<10; i++)

    {

        add_tail_list(list,i);  

    }

    show_list(list);

    insert_list(list,6,88);

    insert_list(list,6,88);

    insert_list(list,6,88);

    insert_list(list,6,88);

    show_list(list);

    TYPE num = -100;

    access_list(list,1,&num);

    printf("num=%d\n",num);

    modify_index_list(list,6,77);

    show_list(list);

    del_index_list(list,1);

    show_list(list);

    del_value_list(list,99);

    modify_value_list(list,88,22);

    show_list(list);

    printf("index=%d\n",query_list(list,90));

    destory_list(list);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoyu1381

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值