Linux数据结构——双向链表2(带头节点)

上一篇讲到了双链表的基本操作(头删头插尾删尾插)

这一篇讲讲双向链表的其他操作

一.查找一个数据

DLinkNode* DLinkListFind(DLinkNode* head, DLinkType to_find) 
{
    if (head == NULL)
        return NULL;
    if (head->next == head)
        return NULL;
    DLinkNode* cur = head->next;
    for(; cur->next != head;cur = cur->next)
    {
        if(cur->data == to_find)
            return cur;
    }
    return NULL;
}

思路:遍历,找到含有这个数据的节点,返回该节点的地址

1.指针的合法性判断

2.空链表判断

3.遍历

二.指定位置之前插入一个节点

void DLinkListInsert(DLinkNode* pos, DLinkType value)
{
    if (pos == NULL)
        return;
    DLinkNode* insert = CreatDLinkNode(value);
    DLinkNode* insert_pre = pos->prev;
    insert->next = pos;
    pos->prev = insert;
    insert_pre->next = insert;
    insert->prev = insert_pre; 
    return;
}

思路:修改两组指针的指向

1.指针合法性判断

2.创建一个节点

3.前插

三.指定位置之后插入一个节点

void DLinkListInsertAfter(DLinkNode* pos, DLinkType value)
{
    if (pos == NULL)
        return;
    DLinkNode* insert = CreatDLinkNode(value);
    DLinkNode* insert_next = pos->next;
    insert->next = insert_next;
    insert_next->prev = insert;
    pos->next = insert;
    insert->prev = pos; 
    return;
}

思路:

1.指针合法性判断

2.创建一个节点

3.后插

四.删除指定位置的元素

void DLinkListErase(DLinkNode* head,DLinkNode* pos)//删除指定位置的元素  
{
    if (head == NULL || pos == NULL)
        return;
    if (head->next == head)
        return;
    DLinkNode* cur = head->next;
    for(; cur != head; cur = cur->next)
    {
        if (cur == pos)
        {
            DLinkNode* to_delete = cur;
            DLinkNode* to_delete_prev = cur->prev;
            DLinkNode* to_delete_next = to_delete->next;
            to_delete_prev->next = to_delete_next;
            to_delete_next->prev =to_delete_prev;
            DestroyNode(to_delete);
            break;
        }
    }
    return;

}

思路:遍历

1.两个指针的合法性判断

2.空链表判断

3.遍历找该位置,找到则删除(修改一组指针)

五.删除指定值元素(链表中若有多个相同元素,删除第一个)

void DLinkListRemove(DLinkNode* head,DLinkType value) //删除指定值的元素  
{
    if (head == NULL)
        return;
    if (head->next == head)
        return;
    DLinkNode* cur = head->next;
    for(; cur != head; cur = cur->next)
    {
        if (cur->data == value)
        {
            DLinkNode* to_delete = cur;
            DLinkNode* to_delete_prev = cur->prev;
            DLinkNode* to_delete_next = to_delete->next;
            to_delete_prev->next = to_delete_next;
            to_delete_next->prev =to_delete_prev;
            DestroyNode(to_delete);
            break;
        }
    }
    return;
}

思路:遍历

1.指针合法性判断

2.空链表判断

3.遍历查找值,找到则删除节点(修改一组指针)

六.删除指定值元素(链表中若有多个相同元素,删除所有)

void DLinkListRemoveAll(DLinkNode* head,DLinkType value)//删除所有相同值得元素 
{
    if (head == NULL)
        return;
    if (head->next == head)
        return;
    DLinkNode* cur = head->next;
    for(; cur != head; cur = cur->next)
    {
        if (cur->data == value)
        {
            DLinkNode* to_delete = cur;
            DLinkNode* to_delete_prev = cur->prev;
            DLinkNode* to_delete_next = to_delete->next;
            to_delete_prev->next = to_delete_next;
            to_delete_next->prev =to_delete_prev;
            DestroyNode(to_delete);
        }
    }
    return;
}

思路同上一个一样,只不过找到一个相同元素,在循环内不要break跳出循环就行了。

七.求链表长度

int DLinkListSize(DLinkNode* head) //链表长度  
{
    if ( head == NULL )
        return -1;
    if ( head == head->next )
        return 0;
    size_t count = 0;
    DLinkNode* cur = head->next;
    while (cur != head)
    {
        count++;
        cur = cur->next;
    }
    return count;
}

思路:遍历+计数器

1.指针的合法性判断

2.空链表判断

3.定义一个计数器,遍历链表,返回计数器的值

所有关于双向链表的测试代码如下:

void TestDLinkListPushBack()
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPrintChar(head, "尾插打印双向链表");
}
void TestDLinkListPopBack()
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPopBack(head);
    DLinkListPrintChar(head, "尾删打印双向链表");
}
void TestDLinkListPushFront() 
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPushFront(head,'d'); 
    DLinkListPrintChar(head, "头插 d");
}
void TestDLinkListPopFront() 
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPopFront(head); 
    DLinkListPrintChar(head, "头删");
}
void TestDLinkListErase() 
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkNode* find = DLinkListFind(head, 'b');
    DLinkListErase(head, find);
    DLinkListPrintChar(head, "找到b,并删掉");
}
void TestDLinkListRemove()
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPushBack(head,'a');
    DLinkListRemove(head, 'a'); //删除指定值的元素  
    DLinkListPrintChar(head, "删掉元素a");
}
void TestDLinkListRemoveAll()
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListPushBack(head,'a');
    DLinkListRemoveAll(head, 'a'); //删除指定值的元素  
    DLinkListPrintChar(head, "删掉所有元素a");
}

void TestDLinkListDestory()
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    DLinkListDestory(&head);
    DLinkListPrintChar(head, "双链表销毁");
}
void TestDLinkListSize()
{
    DLinkNode* head;
    DLinkListInit(&head);
    DLinkListPushBack(head,'a');
    DLinkListPushBack(head,'b');
    DLinkListPushBack(head,'c');
    DLinkListPushBack(head,'d');
    int ret = DLinkListSize(head); //链表长度  
    DLinkListPrintChar(head, "双链表");
    printf("长度为:%d\n",ret);
}
int main()
{
    TestDLinkListPushBack();
    TestDLinkListPopBack();
    TestDLinkListPushFront(); 
    TestDLinkListPopFront(); 
    TestDLinkListErase(); 
    TestDLinkListRemove();
    TestDLinkListRemoveAll();
    TestDLinkListDestory();
    TestDLinkListSize();
    return 0;
}

测试结果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值