双向链表

  1. 意义:

    解决单链表的由于方向性引起的效率问题

    单链表有个缺陷,就是当数据量比较大的时候,当需要对已知节点做删除,排序的等操作时,有一个问题,就是当需要从头节点开始遍历,往往效率较低,

    head==>1 ==> 2 ==>3 ==>4==5

    当我需要删除3这个结点时,就得知道2这个结点的指针,但是只能从头指针开始遍历,才能知道

    双向链表的指针域,除了包含一个后继指针外还包括一个前驱指针,这样子,当拥有一个已知结点时,就不要从头遍历就可以知道这个指针的前驱指针,直接使用即可

     head<==> 1<==>2<==>3

    当已知3这个结点时,可以通过前驱指针,得到2这个结点的指针,然后可以做相应的处理

2.实现

2.1 数据结构

typedef struct node
{
    int data;                                           //数据域
    struct node *next;                                  //指针域
    struct node *prep;
}NODE_t;

next 为后继指针,prep为前驱指针

2.2 创建

NODE_t *CreatNodeList()
{
    NODE_t *head = NULL;

    head = (NODE_t *)malloc(sizeof(NODE_t));
    if(!head)
        exit(-1);
        head->next = NULL; 
    head->prep = NULL;

    return head;
}

2.2 插入

int InsertNode(NODE_t *head,int data)
{
    NODE_t *cur = NULL;

    if(!head)
        exit(-1);

    cur = (NODE_t *)malloc(sizeof(NODE_t));
    if(!cur)
        exit(-1);

    cur->data = data;
    if(!head->next)
    {
        // 当只有头节点时
        cur->next = head->next;
        cur->prep = head;
        head->next = cur;
    }
    else
    {
        // 当链表有节点元素时
        cur->next = head->next;
        head->next->prep = cur;
        cur->prep = head;
        head->next = cur;
    }

    return 0;
}

2.3 查找

NODE_t *findNode(NODE_t *head,int data)
{
    head = head->next;
    while(head)
    {
        if(head->data == data)
        {
            break;
        }
        head = head->next;
    }
    if(head == NULL)
    {
        printf("sorry,%d is not in the list\n",data);
    }

    return head;
}

2.4 删除

int DeleteNodeOfList(NODE_t *head,NODE_t *pfind)
{

    if(pfind->next != NULL)
    {
        pfind->prep->next = pfind->next;
        pfind->next->prep = pfind->prep;
    }
    else
    {
        // 处理尾节点
        pfind->prep->next = NULL;
    }

    free(pfind);
    pfind = NULL;

    return 0;
}

2.5 修改

int UpdateNode(NODE_t *head,int olddata,int newdata)
{
    NODE_t *p = findNode(head,olddata);
    if(p)
    {
        p->data = newdata;
    }

    return 0;
}

2.6 排序

int sortList(NODE_t *head)
{
    int i = 0,j = 0;
    int listlen = 0;
    int tmpData = 0;
    NODE_t *p = NULL;

    // 使用冒泡排序,不动指针域,比较数据域,使用临时变量,将有大小之别的节点的数据域交换
    // 得到链表长度,方便冒泡
    listlen = ListNodeLen(head);

    // 指到首节点
    p = head->next;
    for(i = 0;i < listlen-1;i++)
    {
        // 每一轮从头开始
        p = head->next;
        for(j = 0;j<listlen - i-1;j++)
        {
            // 将小值排在前面
            if(p->data > p->next->data)
            {
                tmpData = p->data;
                p->data = p->next->data;
                p->next->data = tmpData;
            }
            p = p->next;
        }
    }

    return 0;
}

转载于:https://blog.51cto.com/6306331/2073460

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值